Haskell 具有跨度函数的组定义

Haskell group definition with span function

我需要定义组函数是 Haskell,但我只能用 takeWhile 和 dropWhile 来实现,但我不能用 span 来实现。 我需要用跨度来做! 你可以帮帮我吗? 这是我的 tW 和 dW 代码:

group' :: (Eq a) => [a] -> [[a]]
group' [] = []
group' (x:xs) = (x : takeWhile (== x) xs) : group' (dropWhile (== x) xs)

试试这个。

 group' (x:xs) = a:(group' b) where (a,b) = span (==x) (x:xs)

简单地跨越 returns 两个列表,使用给定的函数将它们分开。

查看 hackagespan 的定义,我们发现这个有用的提示:

span p xs is equivalent to (takeWhile p xs, dropWhile p xs)

因此,正如您将函数定义为

group' [] = []
group' (x:xs) = (x : takeWhile (==  x) xs) : group' (dropWhile (== x) xs) 

您可以很容易地看出您的 p 在这种情况下是 (== x)。所以,在上面的跨度定义中替换它

span p xs = (takeWhile p xs, dropWhile p xs)
span (== x) xs = (takeWhile (== x) xs, dropWhile (== x) xs)

跨越 returns 一对列表,因此您可以使用 fstsnd 访问它们。 所以我们有

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 中使用的定义)替换为其他定义 (span)!