简体   繁体   English

从功能应用到功能组合的Haskell类型错误

[英]Haskell Type Error From Function Application to Function Composition

This question is related to this Function Composition VS Function Application which answered by antal sz. 这个问题与由antal sz回答的此功能组成VS功能应用程序有关。

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. 谢谢。

That's just because function application xy has higher precedence than composition x . y 那只是因为函数应用程序xy优先级高于合成x . y优先级x . y 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) 这被解析为test xs = not . (null xs) test xs = not . (null xs) . 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. 当然, null xs类型为Bool ,并且您不能编写布尔值,因此会出现类型错误。 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 ( eg the argument to map or filter ), but specify the rest. 一个示例是将函数组合用于某些事物( 例如 mapfilter的参数),但指定其余部分。 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 ). 这部分是无点的(例如, not . p ,我们省略了最后一个参数),但是部分是无点的(存在pf )。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM