3

I have two functions:

fun1 :: Int -> [Int]
fun2 :: [Int] -> [Int]

fun2 accept Int list and apply fun1 to each element of this list with help map. But fun1 return [Int]. So, I have type conflict. How to solve my problem?

5
  • Should fun2 be as follows fun2 :: [Int] -> [[Int]] Commented Apr 30, 2015 at 10:41
  • 1
    Also I'm not entirely sure what you are trying to do? Is it just to fix the type conflict? Commented Apr 30, 2015 at 10:42
  • 3
    An example could clarify the enquiry... Commented Apr 30, 2015 at 10:44
  • 2
    most likely you are looking for concatMap instead of map (as in fun2 = concatMap fun1) - concatMap fun1 will apply fun1 to each element in the input list but will flatten all the resulting lists into one by concatenating them Commented Apr 30, 2015 at 10:47
  • Sorry guys for my silence. I was out of the computer. Commented Apr 30, 2015 at 17:20

3 Answers 3

6

You likely want a combination of map and concat to achieve it. Assuming fun1 and fun2 are something like this:

fun1 :: Int -> [Int]
fun1 x = [x,x]

fun2 :: [Int] -> [Int]
fun2 = map (+ 1)

solution :: [Int] -> [Int]
solution xs = concat $ map fun1 (fun2 xs)

Or as suggested by @CarstenKonig, you can use concatMap

solution2 :: [Int] -> [Int]
solution2 xs = concatMap fun1 $ fun2 xs

which can be further simplified to:

solution2 :: [Int] -> [Int]
solution2 = concatMap fun1 . fun2
Sign up to request clarification or add additional context in comments.

3 Comments

based on "fun2 accept Int list and apply fun1 to each element of this" I would think that the OP really just wants fun2 = concatMap fun1 though - but yeah that's another one that type-checks ;)
@CarstenKönig I felt this was the natural answer to OP :) But yes, I may be wrong.
that's the problem (not with your answer) - the question is not really good but the OP don't seem to be able to clarify right now
4

The ability to transform [[a]] to [a] is what make List (among other thing) a Monad. Therefore you can use the do notation :

fun2 xs = do 
     x <- xs
     fun1 x

which can the be rewritten fun2 xs = xs >>= fun1 or even better

fun2 = (>>= fun1)

Comments

2

Another way is with list comprehension. Mapping fun1 over the list xs is

fun2' xs = [ fun1 x | x <- xs ]
     --  =  map fun1 xs
     --  =  do x <- xs                -- for each x in xs:
     --        return (fun1 x)        --    yield (fun1 x)

which indeed would have a different type than what you wanted.

To flatten it one step further we do

fun2  xs = [ y | x <- xs, y <- fun1 x ]
     --  = concatMap fun1 xs
     --  =  do x <- xs                -- for each x in xs:
     --        y <- fun1 x            --    for each y in (fun1 x):
     --        return y               --       yield y

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.