rad*_*row 2 haskell gadt dependent-type
我试图从运行时使用一些GADT参数,假设我已经使用DataKinds扩展来允许将数据提升为类型.即拥有
data Num = Zero | Succ Num
data Something (len :: Num) where
Some :: Something len
Run Code Online (Sandbox Code Playgroud)
我想有功能
toNum :: Something len -> Num
Run Code Online (Sandbox Code Playgroud)
对于任何人Some :: Something n将返回n:
toNum (s :: Something n) = n
Run Code Online (Sandbox Code Playgroud)
哪个在Haskell中无效.有可能这样做吗?
在Haskell中,这是不可能的,因为类型在运行时被擦除.也就是说,当程序运行时,内存中没有关于let类型中索引值的信息.
为了克服这个问题,我们需要强制Haskell在运行时将内存保留在内存中.这通常使用单例辅助类型完成:
data Num = Zero | Succ Num
data SNum (n :: Num) where
SZero :: SNum 'Zero
SSucc :: SNum n -> SNum ('Succ n)
data Something (len :: Num) where
Some :: SNum len -> Something len
Run Code Online (Sandbox Code Playgroud)
使用此功能,您可以轻松编写
sToNum :: SNum n -> Num
sToNum SZero = Zero
sToNum (SSucc n) = Succ (sToNum n)
Run Code Online (Sandbox Code Playgroud)
然后
toNum :: Something len -> Num
toNum (Some n) = sToNum n
Run Code Online (Sandbox Code Playgroud)
如果你查找"haskell singletons",你应该找到几个例子.甚至还有一个singletons库可以使其部分自动化.
如果/当"依赖Haskell"将被释放,我们将拥有更少的繁琐工具供我们使用.目前,单身人士工作,但有时他们很麻烦.不过,目前我们还是要使用它们.