我对Haskell 'length'函数的重新定义不起作用



有人能解释一下我如何修复我的程序吗。对于Haskell来说,这是一个非常新的尝试,它试图创建一个length函数来计算任何类型的列表的长度。

我的目标是使用data来做到这一点,因为我想创建一个全新的类型来实现这一点(这是我目前正在学习的Haskell领域,这就是为什么它可能不是该功能的最有效实现(

data List a = Nil | Cons a (List a)

len :: List a -> Int
len Nil         = 0
len (Cons _ xs) = 1 + len xs

如果我在len [1,2,3]上运行它我得到错误:

• Couldn't match expected type ‘List a0’
with actual type ‘[Integer]’
• In the first argument of ‘len’, namely ‘[1, 2, 3]’
In the expression: len [1, 2, 3]
In an equation for ‘it’: it = len [1, 2, 3]

函数定义是正确的,但[1,2,3]不是List a对象,而是[a](或更规范的[] a(。像[1,2,3]List Int一样的列表是:

len(Cons 1 (Cons 2 (Cons 3 Nil)))

或者,您可以使List a成为IsList类型类的实例,然后使用-XOverloadedLists扩展名:

{-# LANGUAGETypeFamilies#-}
import GHC.Exts(IsList(Item, fromList, toList))
instanceIsList (List a)where
type Item (List a) = a
fromList = foldr Cons Nil
toList Nil = []
toList (Cons x xs) = x : toList xs

然后我们可以使用OverloadedLists扩展:

$ ghci -XOverloadedLists -XTypeFamilies
GHCi, version 8.0.2: http://www.haskell.org/ghc/  :? for help
Loaded GHCi configuration from /home/kommusoft/.ghci
Prelude> data List a = Nil | Cons a (List a)
Prelude> import GHC.Exts(IsList(Item, fromList, toList))
Prelude GHC.Exts> :{
Prelude GHC.Exts| instance IsList (List a) where
Prelude GHC.Exts|     type Item (List a) = a
Prelude GHC.Exts|     fromList = foldr Cons Nil
Prelude GHC.Exts|     toList Nil = []
Prelude GHC.Exts|     toList (Cons x xs) = x : toList xs
Prelude GHC.Exts| :}
Prelude GHC.Exts> :{
Prelude GHC.Exts| len :: List a -> Int
Prelude GHC.Exts| len Nil         = 0
Prelude GHC.Exts| len (Cons _ xs) = 1 + len xs
Prelude GHC.Exts| :}
Prelude GHC.Exts> len [1,2,3]
3

最新更新