Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ConcatMap in haskell without ++

Tags:

haskell

I'm trying to write the code for Haskell concatmap without using the ++ operator where

concatMap :: (a -> [b]) -> [a] -> [b]

and producing the same result of

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

I'm quite new to Haskell and this was just an exercise I found. Actually, I do not even know if this can be done.

like image 611
Simone Masiero Avatar asked Jun 11 '19 16:06

Simone Masiero


People also ask

What is the difference between concatmap&map in JavaScript?

The ConcatMap creates an inner observable, subscribes to it, and emits its value as observable. It emits the value in the order in which it creates the observable. The Following example shows the difference between ConcatMap & Map. The Map operator below maps the value coming from the source observable to a new value by multiplying it by 2.

How to use map () function in Haskell?

Working of map in Haskell is as follows: Whenever we want to apply a function on each element of a given list and produce a new list consisting of the updated elements, then we make use of a function called map () function in Haskell.

What is a concatmap in angular?

The Angular ConcatMap maps each value from the source observable into an inner observable, subscribes to it, and then starts emitting the values from it replacing the original value. It creates a new inner observable for every value it receives from the Source.

What does concatmap do?

What does concatMap do? I know what concat and map do. Is it just both of them put together or is it a completely different function? Show activity on this post. Yes, the concatMap function is just concat and map put together. Hence the name. Putting functions together simply means composing them:


3 Answers

Here's a way that makes the state of the computation explicit:

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 [] [] = []

This maintains the current list of bs, filling it up whenever it's empty.

like image 109
dfeuer Avatar answered Oct 24 '22 01:10

dfeuer


This might be cheating, but how about:

myConcatMap f s = concat (map f s)

The concat function uses some sort of ++ in its source code, so that is why you might not like it. You can try to use an alternative concat that does list comprehensions, it has a more "from scratch" feeling.

myconcat ll = [y | x <- ll, y <- x]
like image 35
Juan Carlos Ramirez Avatar answered Oct 23 '22 23:10

Juan Carlos Ramirez


You can use the fact that foldr (:) = flip (++)

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

Or pointfree:

concatMap = flip foldr [] . (flip (foldr (:)) .)
like image 1
Jeremy List Avatar answered Oct 23 '22 23:10

Jeremy List