This question is related to this Function Composition VS Function Application which answered by antal s-z.
How you can get this ?
map has type (a -> b) -> [a] -> [b]
head has type [a] -> a
map head has type [[a]] -> [a]
Why the following code has type error for function composition ?
test :: [Char] -> Bool
test xs = not . null xs
getMiddleInitials :: [String] -> [Char]
getMiddleInitials middleNames = map head . filter (\mn -> not . null mn) middleNames
but this does not have type error
getFirstElements :: [[a]] -> [a]
getFirstElements = map head . filter (not . null)
Is it a must to write a point free function in order to utilize the function composition ? I still not v开发者_如何学Goery understand the usage of function composition.
Please help. Thanks.
That's just because function application x y has higher precedence than composition x . y
test :: [Char] -> Bool
test xs = (not . null) xs
-- # ^ ^
getMiddleInitials :: [String] -> [Char]
getMiddleInitials middleNames = (map head . filter (\mn -> (not . null) mn)) middleNames
-- # ^ ^ ^ ^
Your error here is actually really simple. If you remember the last part of my answer to your last question, the . operator has higher precedence than anything except for function application. Thus, consider your example of
test :: [Char] -> Bool
test xs = not . null xs
This is parsed as test xs = not . (null xs). Of course, null xs has type Bool, and you can't compose a boolean, and so you get a type error. Thus, you could make your examples work like so:
test :: [Char] -> Bool
test xs = (not . null) xs
getMiddleInitials :: [String] -> [Char]
getMiddleInitials middleNames =
(map head . filter (\mn -> (not . null) mn)) middleNames
Of course, writing it this way is unusual, but it would work fine.
And no, there are other uses of function composition besides point-free style. One example is to use function composition for some things (e.g. the argument to map or filter), but specify the rest. For instance, take this contrived example:
rejectMapping :: (a -> Bool) -> (a -> b) -> [a] -> [b]
rejectMapping p f = map f . filter (not . p)
This is partly point-free (not . p, for instance, and we left off the final argument), but partly point-full (the existence of p and f).
加载中,请稍侯......
精彩评论