Haskell类型级别文字Nat:状态?
GHC具有类型级别的文本NAT。我可以在这里读到一些关于他们的东西,例如: 不幸的是,关于它们的文档似乎很少,而且我试图对它们进行的任何操作实际上都不起作用 中的注释18提到了这个简单的大小参数化向量示例(我添加了语言pragmas和import语句): 当时它不起作用,但后来应该对实现进行了修改,使其起作用。那是5年前的事了。。。但它在我的GHC 7.10.1上不起作用:Haskell类型级别文字Nat:状态?,haskell,dependent-type,Haskell,Dependent Type,GHC具有类型级别的文本NAT。我可以在这里读到一些关于他们的东西,例如: 不幸的是,关于它们的文档似乎很少,而且我试图对它们进行的任何操作实际上都不起作用 中的注释18提到了这个简单的大小参数化向量示例(我添加了语言pragmas和import语句): 当时它不起作用,但后来应该对实现进行了修改,使其起作用。那是5年前的事了。。。但它在我的GHC 7.10.1上不起作用: trash.hs:15:20: Could not deduce ((n + m) ~ ((n1 + m) +
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)
这是怎么回事?类型级别的文本NAT应该可以用于这类事情吗?如果是,我如何实现(+++)函数?如果没有,它们的用例是什么?正如评论员所提到的,typechecker目前无法实现这个等式,因为它们需要代数。你和我都知道,给定的
n=n1+m=n1+m+1
,没有人教过GHC typechecker如何执行这种算法。在Ada、Idris或Coq等语言中,您可以向编译器传授这些规则,或者在库中向您提供算术规则,但在Haskell中,typechecker更为严格(但在我看来,对现实编程更为友好),不幸的是,您不得不求助于typechecker插件
据我所知,在这个问题上最积极的人就是其中之一。那份报纸在愚蠢的ACM付费墙后面,但你可以找到他的——解释得很好!。他的演讲使用了和你一样的例子,永远流行的向量。正在将其合并到主线GHC中,但据我所知,没有设定日期。现在,你必须使用typechecker插件,这并不坏。毕竟,最初的目的是在不必将所有内容都合并到源代码中的情况下实现这样有趣的工作。对于模块化,有一些东西值得一提 我认为这是预定的最终工作在GHC-7.12。。。但在7.10中,你至少可以做到这一点。谢谢你指出这一点。但是我看到,即使有了这个插件,如果不绕过类型系统,你显然还是做不了很多事情。请看UNat定义中“不安全”的用法。是的,这有点尴尬。到目前为止,我所做的不是使用
GHC.TypeLits
而是使用codata样式的类型类,将递归方案等提升到Nat
-限定级别,而不是显式解决任何数字等式。检查Richard Eisenberg在向GHC添加依赖类型方面做了大量工作。同意!在今年的Haskell Future 2015上,他就依赖类型的路线图(针对GHC 8.0和9.0)做了精彩的介绍:
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)