首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么"map (filter fst)“类型[(Bool,a)]] -> [[(Bool,a)]”?

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

Stack Overflow用户
提问于 2014-03-19 11:45:22
回答 6查看 503关注 0票数 7

我想弄明白为什么这个函数

代码语言:javascript
复制
map (filter fst)

有类型

代码语言:javascript
复制
[[(Bool, a)]] -> [[(Bool, a)]]

如果过滤器必须接收返回Bool类型的函数,而fst只返回元组的第一个元素,那么"filter fst“如何工作呢?

代码语言:javascript
复制
filter :: (a -> Bool) -> [a] -> [a]
fst :: (a, b) -> a

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

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2014-03-19 12:08:19

如果过滤器必须接收返回Bool类型的函数,而fst只返回元组的第一个元素,那么"filter fst“如何工作呢?

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

过滤器必须接收返回Bool类型的函数。

好的,让我们看看您要传递的是什么:fstfst是一个函数吗?是的,所以我们把第一部分弄下来了。它返回一个Bool吗?好吧,让我们看看它的作用:

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

因此,如果元组的第一个元素是Bool,那么是的,它确实返回一个bool!但是,如果元组的第一个元素不是Bool,那么它不会,而且会使打字机失败。

让我们再看一看你提供的类型。我将更改类型变量的名称,以使事情更清楚:

代码语言:javascript
复制
filter :: (a -> Bool) -> [a] -> [a]
fst :: (b, c) -> b

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

代码语言:javascript
复制
filter fst :: [(Bool, c)] -> [(Bool, c)]

最后,map的类型是:

代码语言:javascript
复制
map :: (d -> e) -> [d] -> [e]

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

map (filter fst)将我们前面定义的filter fst作为第一个参数传递给map。用参数代替d和结果来代替e,我们可以看到这个函数必须是[(Bool, c)] -> [(Bool, c)],换句话说,de都是(Bool, c)。将它们插入到最终类型的函数中:

代码语言:javascript
复制
map (filter fst) :: [[(Bool, c)]] -> [[(Bool, c)]]
票数 16
EN

Stack Overflow用户

发布于 2014-03-19 11:58:51

fst是一个返回布尔值的函数,只要您将元组限制为第一个元素(第二个元素可以是任何东西,因此就可以是(Bool, a) )。

票数 2
EN

Stack Overflow用户

发布于 2014-03-19 11:59:36

代码语言:javascript
复制
:t filter    -- (a -> Bool) -> [a] -> [a]
:t fst       -- (a,b) -> a

但是,我们也可以为fst交换类型变量以获得:

代码语言:javascript
复制
:t fst       -- (c,b) -> c

因此,filter的第一个参数具有a -> Bool类型,而fst本身是(c,b) -> c。现在我们尝试将其结合起来(我认为这被称为统一):

代码语言:javascript
复制
1st arg of filter:  a     -> Bool
fst:                (c,b) -> c

由此,我们可以推断出c必须是Bool (因为右边必须相等)并获得:

代码语言:javascript
复制
1st arg of filter:  a        -> Bool
fst:                (Bool,b) -> Bool

根据上述,我们推断a必须是(Bool,b),并获得:

代码语言:javascript
复制
1st arg of filter:  (Bool,b) -> Bool
fst:                (Bool,b) -> Bool

我们就完了。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22504808

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档