2011-02-06 69 views
20

当我遇到solutionProblem 19时,我在做99 Problems in Haskell,我没有完全理解。模式匹配中的Haskell(n + 1)

任务是编写工作原理是这样

*Main> rotate ['a','b','c','d','e','f','g','h'] 3 
"defghabc" 

*Main> rotate ['a','b','c','d','e','f','g','h'] (-2) 
"ghabcdef" 

一个提供解决方案旋转功能是

rotate [] _ = [] 
rotate l 0 = l 
rotate (x:xs) (n+1) = rotate (xs ++ [x]) n 
rotate l n = rotate l (length l + n) 

我不明白是怎么的模式匹配都不能达到第四线。这似乎与(n+1)有关,因此当n为负值时,第三行不匹配,因此取第四行。如果是这种情况,为什么符号(n+1)这样工作。不是那种武断的,或者是我没有意识到的习惯(数学?)?

因为我理解的方式是,在第三行中递归调用旋转,参数n减1。所以我会认为

rotate [] _ = [] 
rotate l 0 = l 
rotate (x:xs) n = rotate (xs ++ [x]) (n-1) 
rotate l n = rotate l (length l + n) 

是等效的。但事实并非如此。此定义给出以下警告

Warning: Pattern match(es) are overlapped 
     In the definition of `rotate': rotate l n = ... 

而前者的定义编译得很好。

回答

26

这是所谓的“n + k模式”的特定情况,通常不喜欢,并且will be has been removed from the language。有关更多信息,请参见here

Here是n + k中图案的很好的说明,其中引用了Haskell的98报告(重点煤矿)执行以下操作:

匹配的n + k中图案(其中n是 变量并且k是一个正整数 字面值)v 成功,如果 x> = k,导致n 与x-k的绑定,否则失败。再次, 函数> =和 - 被重载, 取决于模式的类型。 如果比较 分歧,则匹配发散。

文字k的解释是 与数字文字 相同,但只允许使用整数 文字。

因此,如果您怀疑n至少为1,那么n+1才会匹配。您的替代代码将删除此限制,从而导致模式匹配重叠。

+0

“这是所谓的”n + k模式“的特定情况,通常不喜欢”。我认为更好的解决方案可能会引入一种自然数的类型,可用于表示* size *,并定义自然数上的* n + 1 *模式。在Haskell和大多数语言(如C/C++)中缺少这种类型,我们看到定义`unsigned int`,`size_t`(这真的很自然)以及相关的signed和unsigne类型之间的比较问题等等的痛苦。自然,我们可以对结构的大小进行案例分析,这是非常基础的,而且在Haskell中很容易。 – tinlyx 2016-01-05 15:01:31