2

这个问题与antal sz 回答的这个Function Composition VS Function Application有关。

你怎么能得到这个?

map has type (a -> b) -> [a] -> [b]
head has type [a] -> a
map head  has type [[a]] -> [a]

为什么下面的代码有函数组合的类型错误?

 test :: [Char] -> Bool
 test xs = not . null xs

 getMiddleInitials :: [String] -> [Char]
 getMiddleInitials middleNames = map head . filter (\mn -> not . null mn) middleNames

但这没有类型错误

getFirstElements :: [[a]] -> [a]
getFirstElements = map head . filter (not . null)

为了利用函数组合,是否必须编写一个无点函数?我还是不太明白函数组合的用法。

请帮忙。谢谢。

4

2 回答 2

4

那只是因为函数应用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
 -- #                            ^                          ^          ^    ^
于 2010-06-26T10:09:28.400 回答
3

您在这里的错误实际上非常简单。如果您还记得我对上一个问题的回答的最后一部分,那么.运算符的优先级高于函数应用之外的任何内容。因此,考虑你的例子

test :: [Char] -> Bool
test xs = not . null xs

这被解析为test xs = not . (null xs). 当然,null xs有 type Bool,你不能组成一个布尔值,所以你会得到一个类型错误。因此,您可以使您的示例像这样工作:

test :: [Char] -> Bool
test xs = (not . null) xs

getMiddleInitials :: [String] -> [Char]
getMiddleInitials middleNames =
  (map head . filter (\mn -> (not . null) mn)) middleNames

当然,以这种方式编写它是不寻常的,但它会工作得很好。

不,除了无点样式之外,函数组合还有其他用途。一个例子是对某些事情使用函数组合(例如mapor的参数filter),但指定其余的。例如,举这个人为的例子:

rejectMapping :: (a -> Bool) -> (a -> b) -> [a] -> [b]
rejectMapping p f = map f . filter (not . p)

这部分是无点的(not . p例如,我们省略了最后一个参数),但部分是完全的(和的存在pf

于 2010-06-26T10:14:55.067 回答