Haskell对函数定义中的顺序敏感吗?

时间:2015-04-30 07:23:41

标签: haskell

我正在尝试Haskell 99问题,我的第一次尝试就是这个问题。尽管解决方案可能有点不正确,但我只是想知道为什么Haskell会对第一个问题发出警告并输出错误的结果

> let { mylast (x:xs) = mylast xs; mylast [] = 0 ;mylast [x] = x;}
Pattern match(es) are overlapped

> mylast [1,2,3,58,8,6,1,231,10]
> 0

但下面的代码执行得很好。

> let { mylast [] = 0 ;mylast [x] = x;mylast (x:xs) = mylast xs;}
> mylast [1,2,3,58,8,6,1,231,10]
> 10

2 个答案:

答案 0 :(得分:11)

是的,函数定义中的模式按指定的顺序尝试,并且(仅)使用第一个匹配的行。

所以在你的定义中

mylast (x:xs) = mylast xs
mylast [] = 0
mylast [x] = x

(为了清晰起见重新格式化),非空列表将始终由第一行处理,甚至是列表[x]x=xxs=[])。因此,对mylast的计算将很乐意忽略列表中的每个元素,最后查看[],从而返回0

答案 1 :(得分:7)

...换句话说,Haskell并不认为两个匹配中哪一个更通用,然后首先使用更具体的匹配。它只是考虑“它匹配还是不匹配?”

在某些情况下,不可能说两个匹配中的哪一个更具体。例如,

foo 0 1

如果Haskell应该选择最具体的匹配模式,那么{{1}}应该得到什么结果?

你需要为这些函数设置一些任意的断路器,并且在Haskell中只需要顺序:总是首先匹配上部子句