【问题标题】:Type classes in NimNim 中的类型类
【发布时间】:2015-01-14 17:55:06
【问题描述】:

我正在尝试在 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)

我省略了nextminmax 的明显定义。

但是,由于Error: 'BoundedGenerator' is not a concrete type,上述内容无法编译

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

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

【问题讨论】:

    标签: typeclass nim-lang


    【解决方案1】:

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

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

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

    【讨论】:

    • multimethods 和 vtables 在运行时都使用动态调度,但似乎在大多数情况下这不是必需的。事实上,通常大多数类型信息在编译时就已知,正确实现的解析可以是静态的。事实上,我认为现在我更好地理解了这个错误,在我看来它与 Nim 类型类和 C++ 接口之间的区别无关。相反,我认为只是 Nim 无法确定 Uniform 的正确大小,因为 BoundedGenerator[int] 的实现可能具有可变大小。
    • 嗯,我应该知道这个错误是什么意思,因为我将它添加到编译器中:) BoundedGenerator[int] 不是可以实例化的特定类型 - 它只是对类别的可验证描述类型,其行为类似于 BoundedGenerators。您可以创建许多符合该描述的具体对象类型。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-31
    相关资源
    最近更新 更多