我已经看到了几个在参数中使用函数的Haskell代码示例,但我永远无法让它为我工作。
示例:
-- Compute the nth number of the Fibonacci Sequence
fib 0 = 1
fib 1 = 1
fib (n + 2) = fib (n + 1) + fib n
当我尝试这个时,我得到了这个错误:
Parse error in pattern: n + 2
这只是一个坏榜样吗?或者我必须做一些特别的事情来使这项工作?
答案 0 :(得分:13)
您所看到的是一种特殊类型的模式匹配,称为“n + k模式”,已从Haskell 2010中删除。请参阅What are "n+k patterns" and why are they banned from Haskell 2010?和http://hackage.haskell.org/trac/haskell-prime/wiki/RemoveNPlusK
答案 1 :(得分:3)
正如Thomas所说,你可以使用View Patterns来实现这个目标:
{-# LANGUAGE ViewPatterns #-}
fib 0 = 1
fib 1 = 1
fib ((subtract 2) -> n) = fib (n + 1) + fib n
由于-
在这种情况下含糊不清,您需要使用subtract
函数。
答案 2 :(得分:2)
我会尽力帮忙,成为Haskell的新手。
我认为问题在于你无法匹配(n + 2)。 从逻辑的角度来看,任何参数“n”都不会匹配“n + 2”,因此永远不会选择第三条规则进行评估。
你可以像Michael所说的那样重写它:
fib n = fib (n - 1) + fib (n - 2)
或使用警卫在函数中定义整个fibonnaci,如:
fibonacci :: Integer -> Integer
fibonacci n
| n == 0 = 0
| (n == 1 || n == 2) = 1
| otherwise = fibonacci(n-1) + fibonacci(n-2)
答案 3 :(得分:2)
模式匹配器仅限于构造函数。因此,虽然您可以匹配函数的参数,例如(:)
(列表构造函数)或Left
和Right
(Either
的构造函数),但您无法匹配算术表达式。
答案 4 :(得分:2)
我认为fib (n+2) = ...
符号不起作用并且是语法错误。你可以使用"正则表达式"参数的样式匹配,如列表或元组:
foo (x:xs) = ...
其中x是列表的头部,x是列表的其余部分或
foo (x:[]) =
如果列表只剩下一个元素并且存储在x中,则匹配。甚至像
这样的复杂比赛foo ((n,(x:xs)):rg) = ...
是可能的。 haskell中的函数定义是一个复杂的主题,可以使用许多不同的样式。
另一种可能性是使用"开关盒"方案:
foo f x | (f x) = [x]
foo _ _ = []
在这种情况下,元素" x"如果条件(f x)
为真,则包含在列表中。在其他情况下,f和x参数并不重要,并返回一个空列表。
为了解决您的问题,我不认为其中任何一个都适用,但为什么不要使用catch-remaining-parameter-values函数定义,例如:
fib n = (fib (n - 1)) + (fib (n - 2))
希望这有帮助,
奥利弗
答案 5 :(得分:1)
由于(+)
是一个函数,因此无法对其进行模式匹配。要做你想做的事,你需要修改第三行:fib n = fib (n - 1) + fib (n - 2)
。