我正在学习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)
答案 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
分配值37
和b
是相同的值'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)