我正在学习haskell并练习一些递归练习。我在这个表达中遇到了我真的不理解的东西。
break' p xs
在满足p
的第一个元素处分解列表xs
,并返回由包含不满足p
的元素的xs
的初始子列表和列表的其余部分(包括满足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)
首先考虑这个(在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')
= ( letl'' = 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)
let (v,w) = break' p xs in (x:v, w)
是模式匹配绑定-v
绑定到结果的第一个元素,w
绑定到第二个元素。
这意味着(几乎(与相同
case break' p xs of
(v, w) -> (x:v, w)
let
绑定比具有单个大小写的大小写表达式更懒惰。