【问题标题】:How to convert this if-then-else to pattern matching?如何将此 if-then-else 转换为模式匹配?
【发布时间】:2014-02-15 00:28:44
【问题描述】:

以下作品:

fib n = let
       f k a b =
           if k==n then b
           else f (k+1) b (a+b)
    in f 1 0 1

但我尝试将 if-then-else 重写为模式匹配,我收到有关重叠模式的警告,它会产生错误的结果(始终为 1)

fib n = let
    f n a b = b
    f k a b = f (k+1) b (a+b)
  in f 1 0 1

为什么?

或者更一般地说,您可以在闭包中进行模式匹配吗?

【问题讨论】:

  • 我省略了“fib 0 = 0”以避免分心
  • n in f n a b 不是来自fib nn。这是一个新的。
  • @Zeta:谢谢,我怎样才能使它成为具有模式匹配的闭包,或者它不能在 Haskell 中完成?
  • 既然除了计算迭代次数之外你没有使用k,为什么不倒计时呢?然后你可以在 1 上匹配。
  • @molbdnilo:是的,我知道,但我很想知道为什么这不起作用(顺便说一下,如果你从 fib 数字开始向上计数,更容易说服自己代码正常工作也“向上”生成)

标签: haskell pattern-matching closures


【解决方案1】:

这里的问题是我们不能编写模式匹配来检查某些参数是否等于某个变量。但是,我们可以进行两个快速更改,以便我们可以跨常量进行模式匹配。

 fib n | n <= 0 = error "Out of range"
 fib n = go (n - 1) 0 1  -- I've renamed your [f] to the more common name [go]
   where go 0 a b = a    -- Base case
         go c a b = go (c - 1) b (a + b)

现在我们倒计时而不是倒计时,这意味着我们可以在0 的基本情况下进行模式匹配,而不是尝试笨拙地检查 if n' == nfib n | ... 的第一种情况只是检查我们是否得到了一个正数。

【讨论】:

    【解决方案2】:

    您可以使用守卫编写类似于您的第二个版本的内容:

    fib n = let
        f n' a b | n == n' = b
        f k a b = f (k+1) b (a+b)
      in f 1 0 1
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-09-08
      • 1970-01-01
      • 2013-12-25
      • 1970-01-01
      • 1970-01-01
      • 2021-01-09
      • 2020-06-26
      • 1970-01-01
      相关资源
      最近更新 更多