如何将此if-then-else转换为模式匹配?

时间:2014-02-14 13:25:47

标签: haskell pattern-matching closures

以下作品:

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

为什么?

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

2 个答案:

答案 0 :(得分:3)

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

 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)

现在我们倒计时而不是up,这意味着我们可以在0的基本情况下进行模式匹配,而不是尝试对n' == n进行尴尬检查。 fib n | ...的第一个案例就是检查我们是否给出了正数。

答案 1 :(得分:1)

你可以使用警卫写下你的第二个版本:

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