(映射的泛型类型。过滤器)

人气:69 发布:2023-01-03 标签: types type-inference filter haskell map-function

问题描述

我不明白为什么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的列表,因为mapfilter都没有列表。我也不明白为什么它只有一个函数,因为两个函数都需要一个函数。

有人能解释一下它是怎么工作的吗?

推荐答案

首先,让我们为函数中的类型使用不同的字母。这样我们就不会被搞糊涂了。

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定义中的df,并获得

(c -> Bool) -> [[c]] -> [[c]]

这就是GHCi告诉我们的。

该函数的实际作用是将过滤器应用到每个子列表;map接受的函数参数是过滤器。所以在GHCI中,

Prelude> import Data.Char
Prelude Data.Char> (map.filter) isDigit ["foo123", "456bar"]
["123","456"]

10