如何"打包" Haskell列表中的一些字符串?

时间:2016-05-18 10:58:14

标签: haskell functional-programming

我想编写一个功能包

pack ['a','a','a','b','c','c','a','a','d','e','e','e'] 
= ["aaa","b","cc","aa","d","eee"]

我该怎么做?我被困了......

3 个答案:

答案 0 :(得分:2)

使用Data.List.group

λ> import Data.List (group)
λ> :t group
group :: Eq a => [a] -> [[a]]
λ> group ['a','a','a','b','c','c','a','a','d','e','e','e']
["aaa","b","cc","aa","d","eee"]

除非你想自己编写这个函数(参见Michael Foukarakis answer

答案 1 :(得分:1)

这里有一些不可思议的东西:

document.getElementById('response').appendChild(
    document.createTextNode(
        xmlHTTP.responseText
    )
);

Data.List已经拥有了您正在寻找的东西。

答案 2 :(得分:1)

我认为值得添加更明确/初学者版本:

pack :: [Char] -> [String]
pack [] = []
pack (c:cs) =
    let (v, s) = findConsecutive [c] cs
    in v : pack s
  where
    findConsecutive ds [] = (ds, [])
    findConsecutive s@(d:ds) t@(e:es)
        | d /= e = (s, t)
        | otherwise = findConsecutive (e:s) es

如果输入是空列表,则结果也是空列表。否则,我们会找到相等的下一个连续Char并将它们组合成一个String,它将在结果列表中返回。为此,我们使用findConsecutive辅助功能。这个函数的行为类似于takeWhile函数,区别在于我们事先知道要使用的谓词(相等比较),并且我们返回消费列表和剩余列表。

换句话说,findConsecutive的签名可以写成:

findConsecutive :: String -> [Char] -> (String, String)

表示它只包含一个只包含重复字符的字符串作为累加器和一个字符被“提取”的列表。它返回一个包含当前元素序列和剩余列表的元组。它的主体应该是直观的:当字符列表不为空且当前元素等于累加器中的元素时,我们将字符添加到累加器并递归到函数中。当我们到达列表的末尾或遇到不同的字符时,函数返回。

可以使用相同的理由来理解pack的主体。