我试图在不使用++
运算符where
concatMap :: (a -> [b]) -> [a] -> [b]
并产生相同的结果
concatMap f = foldr ((++) . f) []
我对Haskell还是很陌生,这只是我发现的一项练习。实际上,我什至不知道是否可以做到这一点。
答案 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 (:)) .)