Haskell Type Error From Function Application to Function Composition

自闭症网瘾萝莉.ら 提交于 2019-12-11 01:41:43

问题


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 very understand the usage of function composition.

Please help. Thanks.


回答1:


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).




回答2:


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
 -- #                            ^                          ^          ^    ^


来源:https://stackoverflow.com/questions/3123457/haskell-type-error-from-function-application-to-function-composition

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!