没有++的haskell中的ConcatMap

时间:2019-06-11 16:01:41

标签: haskell

我试图在不使用++运算符where

的情况下为Haskell concatmap编写代码。
concatMap :: (a -> [b]) -> [a] -> [b]

并产生相同的结果

concatMap f = foldr ((++) . f) []

我对Haskell还是很陌生,这只是我发现的一项练习。实际上,我什至不知道是否可以做到这一点。

3 个答案:

答案 0 :(得分:11)

这是一种使计算状态明确的方法:

concatMap :: (a -> [b]) -> [a] -> [b]
concatMap f = go []
  where
    -- We have b values; use one.
    go (b:bs) as = b : go bs as
    -- No bs left; get some more.
    go [] (a:as) = go (f a) as
    -- Nothing left; we're done.
    go [] [] = []

这将维护b的当前列表,并在其为空时将其填充。

答案 1 :(得分:4)

这可能是作弊,但是如何:

myConcatMap f s = concat (map f s)

concat函数在其源代码中使用某种++,因此这就是您可能不喜欢它的原因。您可以尝试使用确实列出理解的替代方法concat,它具有更多的“从头开始”的感觉。

myconcat ll = [y | x <- ll, y <- x]

答案 2 :(得分:1)

您可以使用foldr (:) = flip (++)

的事实
concatMap f = foldr (flip (foldr (:)) . f) []

或毫无意义:

concatMap = flip foldr [] . (flip (foldr (:)) .)