Haskell函数定义无法按预期工作

时间:2017-07-04 21:06:36

标签: haskell

我是函数式编程和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]

我不确定为什么第一个定义与第二个不同?错误"程序错误:模式匹配失败意味着"?

3 个答案:

答案 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函数都有一个参数。