为什么flip id
被接受为有效表达式? a
b -> c
对Prelude> :t flip
flip :: (a -> b -> c) -> b -> a -> c
Prelude> :t id
id :: a -> a
Prelude> :t flip id
flip id :: b -> (b -> c) -> c
的类型检查不应该失败吗?
{{1}}
答案 0 :(得分:11)
重点是
id :: a -> a
任何类型a
,包括函数类型。也就是说,我们可以选择a = (b -> c)
并获取
id :: (b -> c) -> (b -> c)
,因为->
与右侧相关联,通常写为
id :: (b -> c) -> b -> c
上述内容可以解释为一个带有两个参数的函数:第一个类型为b -> c
,第二个类型为b
。所以我们可以flip
。
答案 1 :(得分:2)
a
类型中的id
可以匹配任何类型,尤其是(b->c)
。
Prelude> :t id :: (b -> c) -> (b -> c)
id :: (b -> c) -> (b -> c) :: (b -> c) -> (b -> c)
->
是右关联的,所以我们可以删除最右边的一组parens
Prelude> :t id :: (b -> c) -> b -> c
id :: (b -> c) -> b -> c :: (b -> c) -> b -> c
将id变为双参数函数。