Haskell 具有静态类型长度的列表的写入长度函数

Haskell 具有静态类型长度的列表的写入长度函数,haskell,types,Haskell,Types,给定一个静态类型长度的列表(以示例为例): 是否可以编写一个长度函数,使用静态类型而不是通常的递归来计算长度 到目前为止,我的努力使我得出结论,这是不可能的,因为需要“取消”类型信息才能在其上重现: class HasLength a where length :: a -> Natural instance HasLength (List el Zero) where length _ = 0 instance HasLength (List el (Succ len

给定一个静态类型长度的列表(以示例为例):

是否可以编写一个长度函数,使用静态类型而不是通常的递归来计算长度

到目前为止,我的努力使我得出结论,这是不可能的,因为需要“取消”类型信息才能在其上重现:

class HasLength a where
    length :: a -> Natural

instance HasLength (List el Zero) where
    length _ = 0

instance HasLength (List el (Succ len)) where
    length _ = 1 + *how to recur on type of len*
然而,我才刚刚开始了解类型可能具有的所有魔力,因此我知道我无法构思解决方案并不意味着没有解决方案

更新

由于length返回自然值,因此我错误地编写了
length\uu=1+…
。正确的例子(使用下面给出的答案)是

例如:

instance HasLength (List el len) => HasLength (List el (Succ len)) where
    length _ = 1 + length (undefined :: List el len)

注意:这需要
ScopedTypeVariables
扩展名

如果您使用
数据种类
扩展,这将更加容易,它将允许您将
自然
升级为一种类型,从而使(升级的)类型
Zero
succn
更易于处理,并消除像
succchar
这样的废话。有几种方法可以做到这一点,但要紧跟文本:

{-#LANGUAGE GADTs, DataKinds, StandaloneDeriving  #-}
data Natural = Zero | Succ Natural deriving (Show,Eq,Ord)

data List el len  where
    Nil  ::                      List el Zero 
    Cons :: el -> List el len -> List el (Succ len) 

deriving instance Show el => Show (List el len)

class HasLength f where len ::  f n -> Natural

instance HasLength (List el) where
    len Nil = Zero
    len (Cons _ xs) = Succ (len xs)

(我还使用了
StandaloneDeriving
,在这种情况下需要自动派生
Show

谢谢应用,你说得对;这要干净得多。但是,当我尝试运行它时,我得到了以下结果:
Kind不匹配HasLength的第一个参数应该有Kind*->*,但是List el在HasLength(List el)的实例声明中有Kind Natural->*,我恐怕不知道对此的适当修复方法。指定HasLength的参数应该具有kind
Natural->*
似乎会使它变得不必要的特定,但我不确定。有什么建议吗?:)嗯,可能是ghc版本——这些东西是ghc-7.4之后的新东西。也许我错过了什么。您可以向
HasLength
中添加一个专门化它的种类签名。但是这个——对于长度索引列表和常规haskell列表的实例,无论是ghc-7.4还是ghc-7.6 Aha,都可以运行良好,您的hpaste清除了它。我缺少各种各样的布拉格语。谢谢!
instance HasLength (List el len) => HasLength (List el (Succ len)) where
    length _ = 1 + length (undefined :: List el len)
{-#LANGUAGE GADTs, DataKinds, StandaloneDeriving  #-}
data Natural = Zero | Succ Natural deriving (Show,Eq,Ord)

data List el len  where
    Nil  ::                      List el Zero 
    Cons :: el -> List el len -> List el (Succ len) 

deriving instance Show el => Show (List el len)

class HasLength f where len ::  f n -> Natural

instance HasLength (List el) where
    len Nil = Zero
    len (Cons _ xs) = Succ (len xs)