【发布时间】:2016-01-22 17:40:56
【问题描述】:
我的一般理解是 Haskell 类型类与 C++ 模板在概念上有一些相似之处 - 即您可以定义函数或类型参数化的类型。但是,C++ 模板的一个有用特性是您也可以使用非类型模板参数。例如,维基百科有一个 great example 说明如何创建编译时阶乘。
理想情况下,我希望在 Haskell 中做同样的事情......而且我几乎可以使用 DataKinds 扩展名。以向量的经典示例为例,该向量在其类型中对其长度进行编码(取自here)。
data Nat = Ze | Su Nat
data Vec :: * -> Nat -> * where
Nil :: Vec a Ze
Cons :: a -> Vec a n -> Vec a (Su n)
我希望能够将向量的类型级别“Nat”“降级”回值级别(可能使用ScopedTypeVariables),以便我可以使用它,因为可以使用 C++ 非类型模板参数作为常量值。 GHC.TypeLits 有点像 KnownNat 类中的一些骇客(它为每个具体文字伪造实例),但我显然不能自己在 Haskell 中编写。
我觉得我想要的东西是不可能的,但我想对为什么它可能不可能有一些直觉。
我觉得依赖类型潜伏在...
【问题讨论】:
-
你可以自己做,但效率低下。
data Nat = Z | S Nat。class Natty (n :: Nat) where natty :: proxy n -> Nat和'Z的一个实例和'S n的另一个实例。 -
当
Vec ()是Nat的单例时,每个人都建议OP 使用单例。这意味着您不需要编写单例,因为对Vec类型的归纳给出了你为 Nat 提供了单身人士的所有力量。您还可以使用简单函数len : Vec x n -> Integer; len Nil = 0; len (Cons _ xs) = 1 + len xs获取向量的类型级别长度的值级别表示。 -
别忘了我们有类型族,它可以和
UndecidableInstances结合。例如。 hackage.haskell.org/package/type-level-numbers
标签: c++ templates haskell types