另一种类型的故障

时间:2012-08-22 17:26:37

标签: haskell

试图了解最终签名是如何推断的:

GHCi> :t (+)
(+) :: Num a => a -> a -> a
GHCi> :t (<*>)
(<*>) :: Applicative f => f (a -> b) -> f a -> f b
GHCi> :t (<*>) (+)
(<*>) (+) :: Num b => (b -> b) -> b -> b

(a' -> a' -> a')必须与f (a -> b)统一,因此f可能属于((->) r)类型:

(<*>) :: Applicative ((->) r) => r -> (a -> b) -> (r -> a) -> (r -> b)
(<*>) (+) ~ a' -> (a' -> a') -> (a' -> a') -> (a' -> a')
(<*>) (+) :: (a' -> a') -> (a' -> a') -- ^^^ got stuck here

有人可以解释如何获得最终类型吗?

感谢。

1 个答案:

答案 0 :(得分:12)

您遇到的问题是->的正确关联性。考虑<*>

的类型
<*> :: (Applicative f) => f (a -> b) -> f a -> f b

f a等于r -> a,我们有

<*> :: f (a -> b) -> f a -> f b
    :: (r -> (a -> b)) -> (r -> a) -> (r -> b)
    :: (r -> a -> b) -> (r -> a) -> (r -> b) -- This is the key line

请注意,它从(r -> (a -> b)) -> other stuff转到(r -> a -> b) -> other stuff,而不是r -> (a -> b) -> other stuff。我们可以删除内括号,因为它们位于箭头的右侧,但我们无法删除外括号,因为它们位于箭头的左侧。

现在,(+) :: (Num a) => a -> a -> a。当<*>r相同而ab相同时,这完全符合(<*>) (+) :: (Num a) => (a -> a) -> (a -> a) :: (Num a) => (a -> a) -> a -> a 的第一个参数,它们都是数字。总之,我们得到了

{{1}}

再次注意我正在删除右边的括号,但不在箭头左侧。