问题描述
我不明白为什么map . filter
泛型类型是map . filter :: (a -> Bool) -> [[a]] -> [[a]]
。
map :: (a -> b) -> [a] -> [b]
和filter :: (a -> Bool) -> [a] -> [a]
。也(.) :: (b -> c) -> (a -> b) -> a -> c
。
所以我猜测是a = (a -> Bool) -> [a]
,b = [a]
,因为筛选器的输出不是函数,所以我认为map . filter
将返回一个需要函数的函数(a -> b)
。
a
的列表,因为map
和filter
都没有列表。我也不明白为什么它只有一个函数,因为两个函数都需要一个函数。
有人能解释一下它是怎么工作的吗?
推荐答案
首先,让我们为函数中的类型使用不同的字母。这样我们就不会被搞糊涂了。
map :: (a -> b) -> [a] -> [b]
filter :: (c -> Bool) -> [c] -> [c]
(.) :: (e -> f) -> (d -> e) -> d -> f
所以现在我们考虑map . filter
。进行替换,我们得到以下结果(~
用于类型相等):
d ~ (c -> Bool)
e ~ ([c] -> [c]) -- Result of 'filter'
e ~ (a -> b) -- Argument of 'map'
f ~ ([a] -> [b])
注意我们如何为e
获取两个类型。通过替换,
a ~ b ~ [c]
因此
f ~ ([[c]] -> [[c])
,因此我们可以替换(.)
和f
定义中的d
和f
,并获得
(c -> Bool) -> [[c]] -> [[c]]
这就是GHCi告诉我们的。
该函数的实际作用是将过滤器应用到每个子列表;map
接受的函数参数是过滤器。所以在GHCI中,
Prelude> import Data.Char
Prelude Data.Char> (map.filter) isDigit ["foo123", "456bar"]
["123","456"]