tags:

views:

147

answers:

2

If this works:

Prelude Data.Char> map toUpper ("sdfsd" ++ "dfgfdg")
"SDFSDDFGFDG"

Then why this doesn't?

Prelude Data.Char> map toUpper . (++) "sdfsd" "dfgfdg"

<interactive>:1:14:
    Couldn't match expected type `a -> [Char]'
           against inferred type `[Char]'
    In the second argument of `(.)', namely `(++) "sdfsd" "dfgfdg"'
    In the expression: map toUpper . (++) "sdfsd" "dfgfdg"
    In the definition of `it': it = map toUpper . (++) "sdfsd" "dfgfdg"
+11  A: 
map toUpper . (++) "sdfsd" "dfgfdg"

is parsed as:

(map toUpper) . ((++) "sdfsd" "dfgfdg")

So basically you're doing

(map toUpper) . "sdfsddfgfdg"

This does not work because the second argument to . needs to be a function, not a string.

I assume you were trying to do something more like (map toUpper . (++)) "sdfsd" "dfgfdg". This also does not work because the return type of ++ is [a] -> [a] while the argument type of map toUpper is [a].

The thing here is that while one might think of ++ as a function that takes two lists and returns a list, it really is a function that takes one list and then returns a function which takes another list and returns a list. To get what you want, you'd need to ++ into a function that takes a tuple of two lists and returns a list. That's called uncurrying. The following works:

map toUpper . (uncurry (++)) $ ("sdfsd", "dfgfdg")
sepp2k
Following your explanation, '(map toUpper . (++) "sdfsd") "dfgfdg"' should do the job. And it does. Thanks.
artemave
And error message now makes sense. Thanks again.
artemave
+2  A: 

You want $ instead of . : map toUpper $ (++) "sdfsd" "dfg" works and does what you want. The reason for this is that $ is a very low-precedence function application, so the corrected version reads as: "Apply the function map toUpper to the result of (++) "sdfsd" "dfg"".

yatima2975