在Nim中键入类

And*_*rea 4 typeclass nim-lang

我试图在Nim中简单地使用类型类.请记住,我从今天早上起就一直在使用Nim,所以我可能一直在做一些愚蠢的事情.

无论如何,我想定义一个伪随机生成器,它生成一个类型的值流T.有时T是数字,因此有必要了解可达到的最小值和最大值 - 比如重新调整值.这是我的类型

type
  Generator*[T] = generic x
    next(var x) is T

  BoundedGenerator*[T] = generic x
    x is Generator[T]
    min(x) is T
    max(x) is T
Run Code Online (Sandbox Code Playgroud)

我也有这样的例子LinearCongruentialGenerator.

假设我想用它来定义Uniform在一个区间内产生浮点值的生成器.我试过了

type Uniform* = object
  gen: BoundedGenerator[int]
  min_p: float
  max_p: float

proc create*(gen: BoundedGenerator[int], min: float, max: float): Uniform =
  return Uniform(gen: gen, min_p: min, max_p: max)
Run Code Online (Sandbox Code Playgroud)

我省略了明显的定义next,minmax.

然而,由于以上原因,上述内容无法编译 Error: 'BoundedGenerator' is not a concrete type

如果我明确地LinearCongruentialGenerator代替BoundedGenerator[int],每个编译,但当然我希望能够切换更复杂的发电机.

任何人都可以帮我理解编译错误吗?

zah*_*zah 6

Nim中的类型类不用于创建抽象多态类型,就像Haskell的类型类和C++的接口一样.相反,它们与C++的概念提案更相似.它们定义了一组任意类型的需求,可以用作泛型函数的重载分辨率标准.

如果要使用抽象类型,可以使用公共基类型定义类型层次结构并使用方法(使用多个调度),也可以使用自己的基于vtable的解决方案.将来,用户定义的类型类将能够自动将匹配的值转换为不同的类型(在重载解析期间).这将使vtable方法非常容易使用,因为具有兼容接口的类型的值将可转换为在外部将vtable携带到对象的"胖指针"(具有可以为其创建具有不同抽象类型的许多指针的益处)宾语).我将在接下来的几个月内实现这些机制,希望在1.0发布之前.

Araq(Nim的主要作者)也有一些计划可以优化某种类型的闭包组合到一个更便宜的表示形式,闭包环境在它们之间共享,最终结果非常接近传统的C++ - 比如vtable携带物体.