【问题标题】:Is it possible to use functions in Haskell parameters?是否可以在 Haskell 参数中使用函数?
【发布时间】:2012-02-25 06:31:08
【问题描述】:

我见过一些在参数中使用函数的 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

这只是一个坏例子吗?还是我必须做一些特别的事情才能完成这项工作?

【问题讨论】:

  • 这些所谓的 (n + k) 模式在前一段时间被 Haskell 禁止。将第三行替换为:fib n = fib (n - 1) + fib (n - 2)
  • NB 还有另一种方法可以查看等式左侧的函数调用:ViewPatterns。我很惊讶它们并不常见。

标签: function haskell parameters


【解决方案1】:

您所看到的是一种特殊类型的模式匹配,称为“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

【讨论】:

    【解决方案2】:

    正如 Thomas 所说,您可以使用视图模式来完成此操作:

    {-# LANGUAGE ViewPatterns #-}
    
    fib 0 = 1
    fib 1 = 1
    fib ((subtract 2) -> n) = fib (n + 1) + fib n
    

    由于在这种情况下- 不明确,您需要改用subtract 函数。

    【讨论】:

      【解决方案3】:

      作为 Haskell 的新手,我会尽力提供帮助。

      我认为问题在于您无法匹配 (n + 2)。 从逻辑的角度来看,任何参数“n”都不会匹配“n+2”,因此您的第三条规则永远不会被选择进行评估。

      您可以像迈克尔所说的那样将其重写为:

      fib n = fib (n - 1) + fib (n - 2)
      

      或者使用守卫在函数中定义整个斐波那契,例如:

      fibonacci :: Integer -> Integer
      fibonacci n
      | n == 0 = 0
      | (n == 1 || n == 2) = 1
      | otherwise = fibonacci(n-1) + fibonacci(n-2)    
      

      【讨论】:

      • 我认为您的意思是 guards,而不是上一个示例中的模式匹配。
      • 确实,就像有人说的那样……一个新手,我最终滥用了这种语言。谢谢。
      【解决方案4】:

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

      【讨论】:

        【解决方案5】:

        我认为fib (n+2) = ... 表示法不起作用并且是语法错误。您可以对参数使用“正则表达式”样式匹配,例如列表或元组:

        foo (x:xs) = ...
        

        其中 x 是列表的头部,xs 是列表的其余部分或

        foo (x:[]) = 
        

        如果列表只剩下一个元素并且存储在x中,则匹配。甚至像

        这样的复杂匹配
        foo ((n,(x:xs)):rg) = ...
        

        是可能的。 haskell 中的函数定义是一个复杂的主题,可以使用很多不同的样式。

        另一种可能性是使用“switch-case”方案:

        foo f x | (f x) = [x]
        foo _ _ = []
        

        在这种情况下,如果条件(f x) 为真,则元素“x”被包装在一个列表中。在其他情况下,f 和 x 参数不感兴趣,并返回一个空列表。

        为了解决你的问题,我认为这些都不适用,但是为什么不抛出一个 catch-remaining-parameter-values 函数定义,比如:

        fib n = (fib (n - 1)) + (fib (n - 2))
        

        希望这会有所帮助,

        奥利弗

        【讨论】:

          【解决方案6】:

          由于(+) 是一个函数,你不能对它进行模式匹配。要执行您想要的操作,您需要将第三行修改为:fib n = fib (n - 1) + fib (n - 2)

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2014-06-03
            • 1970-01-01
            • 1970-01-01
            • 2016-04-11
            • 2013-10-08
            相关资源
            最近更新 更多