2010-06-26 77 views
2

这个问题与这个Function Composition VS Function Application有关,由antal s-z回答。Haskell类型错误从函数应用到函数组合

你如何得到这个?

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) 

它是一个必须以利用函数组合写点免费功能? 我还是不太了解函数组合的用法。

请帮忙。 谢谢。

回答

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 

当然,这样写它是不寻常的,但它会正常工作。

不,除了无点式以外还有其他功能组合的用途。一个例子是对某些事情使用函数合成(,例如参数为mapfilter),但指定其余部分。举例来说,利用这个人为的例子:

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

这部分是点免费(not . p,例如,我们离开的最后一个参数),但部分点满(存在pf)。

+0

真的不明白rejectMapping例子的最后部分。 – peterwkc 2010-06-27 03:07:07

+0

哪部分你不明白?它背后的动机,它应该做什么,或者它是如何工作的?它只使用你已经看过的东西,所以如果你仔细想想,你应该可以遵循它! – 2010-06-27 03:28:51

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