我正在尝试编写自己的多态列表类型 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
提前致谢!
我正在尝试编写自己的多态列表类型 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
提前致谢!
我假设您已将该代码保存在名为 Lists.hs 的文件中
这是len
在 Hugs 中调用函数的方法。
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)
如果你不放这个,Hugs 会假设:.
联想到左边,所以它会认为
'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`
相反,但我不认为那很好。)