元组模式匹配(v,w)= someFunction param_1 param_2如何工作?

时间:2020-10-21 09:33:11

标签: haskell

我正在学习haskell并练习一些递归练习。我碰到了一个我真的不明白的表情。

break' p xs在满足xs的第一个元素处中断列表p,并返回由xs的初始子列表组成的列表对,其中包含不满足条件的元素p,以及列表的其余部分(包括满足p的第一个元素)。

这是签名:

break' :: (a -> Bool) -> [a] -> ([a],[a])

通过案例的模式匹配来定义。在第四行中,表达式(v,w) = break' p xs是什么意思–用表达式定义一个元组?这怎么可能?在这种情况下,该元组上的值如何关联?

break' p [] = ([], [])
break' p (x:xs) | p x = ([], x:xs)
                | otherwise = let (v,w) = break' p xs in (x:v, w)

2 个答案:

答案 0 :(得分:4)

let (v,w) = break' p xs in (x:v, w)

是模式匹配的绑定-v绑定到结果的第一个元素,w绑定到第二个元素。

表示(几乎)与

相同
case break' p xs of 
    (v, w) -> (x:v, w)

let绑定比带有单个case的case表达式更懒。

答案 1 :(得分:4)

首先考虑这一点(在GHCi提示符下)

Prelude> let (a,b) = (37,'y')

我敢说这样做很清楚:为元组(a,b)分配值(37,'y')与为a分配值37b是相同的值'y',实际上就是这里发生的情况:

Prelude> a
37
Prelude> b
'y'

现在,在命令提示符上实际写出(37,'y')并没有什么特别的。只是一些元组,也可以单独定义:

Prelude> let tup = (37, 'y')
Prelude> let (a,b) = tup

...或者可能是某个函数的结果:

Prelude> let f x = (x, 'y')
Prelude> let (a,b) = f 37
Prelude> a
37
Prelude> b
'y'

要详细说明另一个示例:

lengthAndSum :: [Float] -> (Int, Float)
lengthAndSum [] = (0,0)
lengthAndSum (x:xs) = (l+1, s+x)
 where (l,s) = lengthAndSum xs

然后,例如

lengthAndSum [1,2,3]
      ≡ ( let (l,s) = lengthAndSum [2,3]
          in (l+1, s+1) )
      ≡ ( let (l,s)
               = ( let (l',s') = lengthAndSum [3]
                   in (l'+1, s'+2) )
          in (l+1, s+1) )
      ≡ ( let (l,s)
               = ( let (l',s')
                        = ( let (l'',s'') = lengthAndSum []
                            in (l''+1, s''+3) )
                   in (l'+1, s'+2) )
          in (l+1, s+1) )
      ≡ ( let (l,s)
               = ( let (l',s')
                        = ( let (l'',s'') = (0,0)
                            in (l''+1, s''+3) )
                   in (l'+1, s'+2) )
          in (l+1, s+1) )
      ≡ ( let (l,s)
               = ( let (l',s')
                        = ( let l'' = 0
                                s'' = 0
                            in (l''+1, s''+3) )
                   in (l'+1, s'+2) )
          in (l+1, s+1) )
      ≡ ( let (l,s)
               = ( let (l',s') = (0+1, 0+3)
                   in (l'+1, s'+2) )
          in (l+1, s+1) )
      ≡ ( let (l,s) = (1+1, 3+2)
          in (l+1, s+1) )
      ≡ (2+1, 5+1)(3, 6)
相关问题