我是函数式编程和Haskell的新手。试着去学习它。不确定以下定义有什么问题:
test.h中的函数定义
drop5 [a] = drop 5 [a]
尝试使用此功能我收到程序错误
$:load test.h
$drop5 [2,3,4,5,6,7,8]
Program error: pattern match failure: drop5 [2,3,4,5,6,7,8]
$:t drop5
drop5 :: [a] -> [a]
当我将定义更改为以下时,它起作用;这意味着它需要一个列表并删除列表的前5个元素
drop5 ns = drop 5 ns
在这种情况下,当打印类型我看到:
$:t drop5
drop5 :: [a] -> [a]
我不确定为什么第一个定义与第二个不同?错误"程序错误:模式匹配失败意味着"?
答案 0 :(得分:5)
在第一个定义中,[a]
是一个只与一个元素的列表匹配的模式,该元素在规则的右侧部分称为a
。
因此,您将该函数定义为仅接受单例列表。
此外,从一个只有一个元素的列表中删除5个元素显然会导致一个空列表(删除任何正数的元素)。
答案 1 :(得分:4)
您的功能定义:
drop5 [a] = drop 5 [a]
指定只有"触发"对于具有一个元素的列表。实际上,在函数定义中[a]
不是参数的类型,它是模式。模式[a]
意味着我们正在处理一个只包含一个元素的列表。
如果使用-Wall
进行编译,您将获得:
<interactive>:1:1: warning: [-Wincomplete-patterns]
Pattern match(es) are non-exhaustive
In an equation for ‘drop5’:
Patterns not matched:
[]
(_:_:_)
编译器/解释器因此产生一个警告,表明未覆盖两个模式:一个用于空列表,另一个用于带有两个或更多元素的列表。< / p>
答案 2 :(得分:2)
[a]
告诉Haskell列表中只有一个元素,而ns
告诉Haskell它可以是任何东西(如果你想要的话,甚至是布尔值),直到你完成该函数并且它识别出来输出和输入类型。您还可以通过在该行上方添加以下内容来明确告诉Haskell输入和输出类型:
drop5 :: [Integer] -> [Integer]
可以通过GHCI中的:t drop5
找到。
另外,在旁注中,可以减少此代码。通过将其更改为:
drop5 = drop 5
这对你来说可能没有意义,但是当你了解更多时,你应该知道所有Haskell函数都有一个参数。