我对Haskell很新,我正在尝试定义自己的长度函数,如下所示:
lengthz :: [a] -> a
lengthz [] = 0
lengthz n = 1 + length (tail n)
为什么这不编译?或者,我的逻辑是否有问题?
谢谢!
答案 0 :(得分:5)
首先,您对lengthZ
的递归调用中存在拼写错误。解决这个问题,我们遇到了一个新的类型错误:
没有(Num a)的实例
这告诉我们的是,为了使用函数(+)
,我们必须在类型声明中包含类型类Num
作为约束。我们还为列表的元素包含一个不同的类型变量,以便该函数可以应用于包含任何类型元素的列表。因此,我们按如下方式重写函数:
lengthz :: Num b => [a] -> b
lengthz [] = 0
lengthz n = 1 + lengthz (tail n)
正如我们所期望的那样有效:
ghci>> lengthz [1,2,3]
3
ghci>> lengthz []
0
答案 1 :(得分:3)
lengthz
功能的类型为[a] -> a
。
这意味着您需要获取a
项内容列表并返回单个a
内容。如果您有Bool
列表怎么办?您不希望该函数输出Bool
。无论列表中的内容类型如何,都希望返回Int
。
最简单的解决方法是将lengthz
的类型更改为[a] -> Int
。这表示参数可以是任何内容的列表(a
是任何内容,[]
表示它是一个列表),返回类型是Int
。