这个问题与antal s-z回答的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)
为了利用函数组合,是否必须编写无点函数? 我仍然不太了解功能组合的用法。
请帮忙。 谢谢。
答案 0 :(得分: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
-- # ^ ^ ^ ^
答案 1 :(得分:3)
这里的错误实际上非常简单。如果您还记得my answer to your last question的最后一部分,.
运算符的优先级高于除之外的任何函数应用程序。因此,请考虑您的
test :: [Char] -> Bool
test xs = not . null xs
这被解析为test xs = not . (null xs)
。当然,null xs
的类型为Bool
,您无法编写布尔值,因此会出现类型错误。因此,您可以使您的示例如下工作:
test :: [Char] -> Bool
test xs = (not . null) xs
getMiddleInitials :: [String] -> [Char]
getMiddleInitials middleNames =
(map head . filter (\mn -> (not . null) mn)) middleNames
当然,以这种方式编写它是不寻常的,但它会正常工作。
不,除了无点样式之外,还有其他功能组合用途。一个例子是对某些事物使用函数组合(例如 map
或filter
的参数),但指定其余部分。例如,采取这个人为的例子:
rejectMapping :: (a -> Bool) -> (a -> b) -> [a] -> [b]
rejectMapping p f = map f . filter (not . p)
这部分是无点的(例如,not . p
,我们没有留下最终的论点),但部分是点满(p
和f
的存在)。