【发布时间】:2015-11-02 07:13:06
【问题描述】:
GHC 具有类型级别的字面量 Nats。例如,我可以在这里阅读一些关于它们的信息:
https://ghc.haskell.org/trac/ghc/wiki/TypeNats
不幸的是,关于它们的文档似乎很少,而且我尝试对它们做的几乎所有事情都没有真正起作用。
this page 的评论 18 提到了这个大小参数化 Vecs 的简单示例(我添加了 LANGUAGE pragma 和 import 语句):
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE TypeOperators #-}
import GHC.TypeLits
data Vec :: Nat -> * -> * where
Nil :: Vec 0 a
(:>) :: a -> Vec n a -> Vec (n+1) a
(+++) :: Vec n a -> Vec m a -> Vec (n+m) a
Nil +++ bs = bs
(a :> as) +++ bs = a :> (as +++ bs)
当时它没有工作,但后来据说修改了实现,以便它工作。那是 5 年前的事了……但它不适用于我的 GHC 7.10.1:
trash.hs:15:20:
Could not deduce ((n + m) ~ ((n1 + m) + 1))
from the context (n ~ (n1 + 1))
bound by a pattern with constructor
:> :: forall a (n :: Nat). a -> Vec n a -> Vec (n + 1) a,
in an equation for ‘+++’
at trash.hs:15:2-8
NB: ‘+’ is a type function, and may not be injective
Expected type: Vec (n + m) a
Actual type: Vec ((n1 + m) + 1) a
Relevant bindings include
bs :: Vec m a (bound at trash.hs:15:15)
as :: Vec n1 a (bound at trash.hs:15:7)
(+++) :: Vec n a -> Vec m a -> Vec (n + m) a
(bound at trash.hs:14:1)
In the expression: a :> (as +++ bs)
In an equation for ‘+++’: (a :> as) +++ bs = a :> (as +++ bs)
这里有什么问题?类型级文字 Nats 应该可用于这种事情吗?如果是这样,我如何实现(+++)功能?如果不是,它们的用例是什么?
【问题讨论】:
-
我认为这是最终会在 GHC-7.12 中工作......但在 7.10 中,你至少可以load a plugin 来解决问题。
-
感谢您指出这一点。但我看到即使使用那个插件,如果不绕过类型系统,你显然仍然无法做很多事情。参见 UNat here 的定义中 unsafeCoerce 的使用。
-
是的,有点尴尬。到目前为止,我所做的不是使用
GHC.TypeLits,而是坚持to a manually-defined Peano type,使用codata 样式类型类将递归方案等提升到Nat-qualified 级别,而不是显式解决任何数字等式。 -
签出Idris