为什么"map(filter fst)"类型为"[[(Bool,a)]] - > [[(Bool,a)]]"?

Gni*_*ruT 8 haskell types functional-programming type-inference unification

我试图理解为什么功能

map (filter fst)
Run Code Online (Sandbox Code Playgroud)

有类型

[[(Bool, a)]] -> [[(Bool, a)]]
Run Code Online (Sandbox Code Playgroud)

如果过滤器必须接收返回Bool-Type的函数并且fst只返回元组的第一个元素,那么"过滤器fst"如何工作?

filter :: (a -> Bool) -> [a] -> [a]
fst :: (a, b) -> a
Run Code Online (Sandbox Code Playgroud)

有人能解释我吗?谢谢 ;)

dan*_*ght 16

如果过滤器必须接收返回Bool-Type的函数并且fst只返回元组的第一个元素,那么"过滤器fst"如何工作?

从某种意义上说,你已经回答了自己的问题!让我们分解一下:

filter必须接收一个返回Bool-Type的函数

好的,让我们来看看你传递的是什么:fst.是fst功能吗?是的,是的,所以我们已经完成了第一部分.它会返回Bool吗?好吧,让我们来看看它的作用:

fst只返回元组的第一个元素

所以如果一个元组的第一个元素是a Bool,那么是的,它确实会返回一个bool!如果元组的第一个元素是除了a之外的任何元素Bool,那么它就不会,并且会在类型检查中失败.

让我们再看看你提出的类型.我将更改类型变量的名称,以使事情更清晰:

filter :: (a -> Bool) -> [a] -> [a]
fst :: (b, c) -> b
Run Code Online (Sandbox Code Playgroud)

fst取一个(b, c)并返回一个b,并且过滤器期望一个函数接受a并返回一个Bool.我们正在传入fst,所以a上面必须是(b, c)第一个参数fst.我们传入的函数的返回值filter必须是a Bool,因此b上面必须是a Bool.并且c可以是任何东西,因为它根本不被过滤器使用.将值替换为ab给出最终类型filter fst:

filter fst :: [(Bool, c)] -> [(Bool, c)]
Run Code Online (Sandbox Code Playgroud)

最后,类型map是:

map :: (d -> e) -> [d] -> [e]
Run Code Online (Sandbox Code Playgroud)

(同样,我在这里重新命名了类型变量,只是为了将它们与我们上面使用过的变量区分开来,但是请记住它们实际上并不重要,只要它们在范围内是一致的.类型注释)

map (filter fst)filter fst上面定义的我们作为第一个参数传递给map.代的参数d和结果的e,我们可以看到这个功能必须[(Bool, c)] -> [(Bool, c)]的,换句话说这两个de(Bool, c).将这些插入函数我们到达最终类型:

map (filter fst) :: [[(Bool, c)]] -> [[(Bool, c)]]
Run Code Online (Sandbox Code Playgroud)