我正在尝试编写自己的多态列表类型List a,以充当默认库列表。我相信代码是正确的,但我似乎无法在Hugs98中成功调用它。使用List a?类型调用函数和计算非空列表的长度的正确方法是什么?
My Haskell Code is:
data List a = Nil | Cons a (List a)
len :: List a -> Int
len Nil = 0
len (Cons _ xs) = 1 + len xs
提前致谢!
答案 0 :(得分:2)
我假设您已将该代码保存在名为Lists.hs的文件中
以下是如何在Hugs中调用len
函数。
Main> :l Lists
Main> len Nil
0
Main> len (Cons 1 Nil)
1
Main> len (Cons 'a' Nil)
1
Main> len (Cons 'a' (Cons 'b' Nil))
2
Main> len (Cons 'a' (Cons 'b' (Cons 'c' Nil)))
3
但是,括号有点难看。这是一种让它变得更好的方法:
infixr 5 :.
data List a = Nil | a :. (List a)
deriving Show
infixr
行告诉Hugs构造函数:.
应该与右边相关联,因此右边有隐式括号,这意味着
'a' :. 'b' :. Nil = 'a' :. ('b' :. Nil)
如果你不这样做,拥抱会认为:.
左边是同伙,所以会想到
'a' :. 'b' :. Nil = ('a' :. 'b') :. Nil
这没有意义 - 你会得到
Main> 'a' :. 'b' :. Nil
ERROR - Type error in application
*** Expression : 'a' :. 'b'
*** Term : 'b'
*** Type : Char
*** Does not match : List a
或者更令人困惑的是,如果是数字,它会尝试从列表中创建一个数字:
Main> 1 :. 2 :. Nil
ERROR - Cannot infer instance
*** Instance : Num (List a)
*** Expression : 1 :. 2 :. Nil
无论如何,我们做了infixr 5 :.
事情,所以这不会发生。我选择了5的优先级,因为这是:
在标准前奏中的含义。现在我们可以编辑len
以应对新定义:
len :: List a -> Int
len Nil = 0
len (_ :. xs) = 1 + len xs
这样你就得到了
Main> len (4 :. 5 :. 6:. Nil)
3
或者如果您愿意,
Main> len $ 4 :. 5 :. 6:. Nil
3
(你可以做到
infixr 5 `Cons`
相反,但我不认为这很好。)