鉴于:
uncurry :: (a-> b -> c) -> (a,b) -> c
id :: a -> a
调用
uncurry id
产生一个函数类型:(b -> c, b) -> c
我们如何得到这个结果?
如何使用 id (a -> a) 作为 uncurry 的第一个参数,这需要 (a -> b -> c) 函数?
最佳答案
如果我们尝试从使类型解决的角度来看它更容易理解:弄清楚我们需要做什么到id
的类型,使其适合 uncurry
所需的形状.因为我们有:
id :: a -> a
我们还有:
id :: (b -> c) -> (b -> c)
这可以通过替换
b -> c
来查看对于 a
在 id
的原始类型中, 就像你可以替换 Int
而是在确定 id 42
的类型时.然后我们可以去掉右边的括号,因为 (->)
是右结合的:id :: (b -> c) -> b -> c
显示
id
的类型符合 a -> b -> c
的形式, 其中 a
是 b -> c
.换句话说,我们可以 reshape id
的类型,只需专门化它已有的通用类型即可满足所需的形式。理解这一点的另一种方法是查看
uncurry ($)
也有类型 (b -> c, b) -> c
.比较 id
的定义和 ($)
:id :: a -> a
id a = a
($) :: (a -> b) -> a -> b
($) f x = f x
我们可以使后一个定义更加无意义:
($) f = f
在这一点上,
($)
只是 id
的特化到更具体的类型变得清晰。
关于haskell - 为什么这个 Haskell 代码会编译?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8935568/