5

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

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

谁能解释如何获得最终类型?

谢谢。

4

1 回答 1

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. 这完全符合第一个参数<*>when ris same as ais same asb并且它们都是数字。总之,我们明白了

(<*>) (+) :: (Num a) => (a -> a) -> (a -> a)
          :: (Num a) => (a -> a) -> a -> a

再次注意,我删除了右侧的括号,而不是箭头左侧的括号。

于 2012-08-22T17:41:08.057 回答