5

我试图在 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

我也有这样的例子,说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)

next我省略了和min的明显定义max

但是,以上内容无法编译,因为Error: 'BoundedGenerator' is not a concrete type

如果我明确地LinearCongruentialGenerator代替BoundedGenerator[int], 每次编译,但我当然希望能够切换更复杂的生成器。

谁能帮我理解编译器错误?

4

1 回答 1

7

Nim 中的类型类并不像 Haskell 的类型类和 C++ 的接口那样用于创建抽象多态类型。相反,它们更类似于 C++ 的概念提案。它们定义了一组任意类型要求,可用作泛型函数的重载解决标准。

如果您想使用抽象类型,您可以定义一个具有通用基本类型的类型层次结构并使用方法(使用多个 dispatch),或者您可以推出自己的基于 vtable 的解决方案。将来,用户定义的类型类将能够自动将匹配的值转换为不同的类型(在重载决策期间)。这将使 vtable 方法非常易于使用,因为具有兼容接口的类型的值将可转换为“胖指针”,将 vtable 从外部传输到对象(其好处是可以为同一个对象创建许多具有不同抽象类型的指针目的)。我将在接下来的几个月内实现这些机制,希望在 1.0 发布之前。

Araq(Nim 的主要作者)也有一些计划来优化捆绑在一起的特定类型的闭包以更便宜的表示,其中闭包环境在它们之间共享,最终结果非常接近于传统的 C++ 类 vtable - 携带物体。

于 2015-01-15T11:10:11.980 回答