我需要定义组函数为Haskell,但是我只能用takeWhile和dropWhile来做到,但是我不能用span来做到。 我需要用跨度来做! 你可以帮帮我吗? 这是我的tW和dW的代码:
group' :: (Eq a) => [a] -> [[a]]
group' [] = []
group' (x:xs) = (x : takeWhile (== x) xs) : group' (dropWhile (== x) xs)
答案 0 :(得分:2)
尝试一下。
group' (x:xs) = a:(group' b) where (a,b) = span (==x) (x:xs)
Span只是返回两个列表,这些列表使用给定的功能分开。
答案 1 :(得分:2)
看看hackage中span
的定义,我们发现了这个有用的提示:
span p xs等于(takeWhile p xs,dropWhile p xs)
因此,正如您将函数定义为
group' [] = []
group' (x:xs) = (x : takeWhile (== x) xs) : group' (dropWhile (== x) xs)
在这种情况下,您可以轻松地看到您的p
是(== x)
。因此,将其替换为上面的span定义
span p xs = (takeWhile p xs, dropWhile p xs)
span (== x) xs = (takeWhile (== x) xs, dropWhile (== x) xs)
span返回一对列表,因此您可以使用fst
和snd
访问它们。
所以我们有
takeWhile (== x) xs = fst (span (== x) xs)
和
dropWhile (== x) xs = snd (span (== x) xs)
使用此方法,我们可以将它们替换为您的原始函数,如下所示:
group' [] = []
group' (x:xs) = (x : fst (span (== x) xs) ) : group' (snd (span (== x) xs) )
当然,用相同的参数两次调用同一函数(span (== x) xs
)是不好的,所以让我们用let
绑定一次调用它:
group' [] = []
group' (x:xs) = let s = span (== x) xs in (x : (fst s)) : group' (snd s)
我很喜欢Haskell最终只是数学而已,您可以仅使用一些代数方程式就可以将某些定义(例如,与takeWhile和dropWhile一起使用的定义)替换为其他定义(跨度)!