Haskell function composition question
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]开发者_如何学C'
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"
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")
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"
".
精彩评论