是否可以在Haskell参数中使用函数?

时间:2012-02-24 15:46:52

标签: function haskell parameters

我已经看到了几个在参数中使用函数的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

这只是一个坏榜样吗?或者我必须做一些特别的事情来使这项工作?

6 个答案:

答案 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)

模式匹配器仅限于构造函数。因此,虽然您可以匹配函数的参数,例如(:)(列表构造函数)或LeftRightEither的构造函数),但您无法匹配算术表达式。

答案 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)