我是Haskell的新手,目前正在学习以进行考试。我一直在学习learnyouahaskell。我不理解group函数中的以下let表达式。
splitWhen :: (a -> Bool) -> [a] -> ([a],[a])
splitWhen p xs = (takeWhile (not . p) xs, dropWhile (not . p) xs)
group :: (Eq a) => [a] -> [[a]]
group [] = []
group (x:xs) = let (group1, rest) = splitWhen (/=x) xs
in (x:group1) : group rest
我知道splitWhen是做什么的:splitWhen even [1,2,3] => ([1],[2,3])
我知道功能组会产生以下结果:
group [1,1,2,1,3,3,3] => [[1,1],[2],[1],[3,3,3]]
我不知道它是如何工作的。有人可以向我解释吗? 谢谢。
答案 0 :(得分:5)
let
表达式是立即应用匿名函数的语法糖。也就是说,
let (group1, rest) = splitWhen (/=x) xs
in (x:group1) : group rest
等同于
(\(group1, rest) -> (x:group1) : group rest) (splitWhen (/=x) xs)
换一种说法,let
反转函数主体和函数参数的位置。比较
let name = value in body
( \name -> body ) value
答案 1 :(得分:2)
let (group1, rest) = splitWhen (/=x) xs
这将调用splitWhen (/=x) xs
并在返回的元组上使用模式匹配将其分配给(group1, rest)
。然后可以将这些值用于
in (x:group1) : group rest
计算函数的最终结果。
您可以将其实现为where
子句,并获得相同的行为:
group (x:xs) = (x:group1) : group rest
where (group1, rest) = splitWhen (/=x) xs