从评估级别访问 GADT 约束
Access GADT contstraint from evaluation level
我正在尝试使用运行时的一些 GADT 参数,假设我已经使用 DataKinds
扩展来允许将数据提升为类型。即有
data Num = Zero | Succ Num
data Something (len :: Num) where
Some :: Something len
我想要功能
toNum :: Something len -> Num
对于任何 Some :: Something n
将 return n
:
toNum (s :: Something n) = n
在 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
使用这个你可以轻松编写
sToNum :: SNum n -> Num
sToNum SZero = Zero
sToNum (SSucc n) = Succ (sToNum n)
然后
toNum :: Something len -> Num
toNum (Some n) = sToNum n
如果您查找 "haskell singletons",您应该会找到几个示例。甚至还有一个 singletons
库来部分自动化。
如果/当 "dependent Haskell" 发布时,我们将可以使用不那么笨重的工具。目前,单身人士可以工作,但有时会很麻烦。不过,目前,我们必须使用它们。
我正在尝试使用运行时的一些 GADT 参数,假设我已经使用 DataKinds
扩展来允许将数据提升为类型。即有
data Num = Zero | Succ Num
data Something (len :: Num) where
Some :: Something len
我想要功能
toNum :: Something len -> Num
对于任何 Some :: Something n
将 return n
:
toNum (s :: Something n) = n
在 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
使用这个你可以轻松编写
sToNum :: SNum n -> Num
sToNum SZero = Zero
sToNum (SSucc n) = Succ (sToNum n)
然后
toNum :: Something len -> Num
toNum (Some n) = sToNum n
如果您查找 "haskell singletons",您应该会找到几个示例。甚至还有一个 singletons
库来部分自动化。
如果/当 "dependent Haskell" 发布时,我们将可以使用不那么笨重的工具。目前,单身人士可以工作,但有时会很麻烦。不过,目前,我们必须使用它们。