应用函子。详细输入 <*> 和 <$> 的签名

Applicative functors. Type signatures of <*> and <$> in detail

我们有签名:

(<$>) :: Functor f     =>   (a -> b) -> f a -> f b
(<*>) :: Applicative f => f (a -> b) -> f a -> f b 

让我们来玩一下:

(/)  <$> Just 5       <*> Just 2
=> Just 2.5

((/) <$> Just 5     ) <*> Just 2
=> Just 2.5

( Just (\x -> 5/x ) ) <*> Just 2
=> Just 2.5

问题:

((/) <$> Just 5) <*> Just 2
^^^^^^^^^^^^^^^^     @@@@@@

(<$>) :: Functor f     =>   (a -> b) -> f a -> f b
                                               ^^^
(<*>) :: Applicative f => f (a -> b) -> f a -> f b
                          ^^^^^^^^^^    @@@

我认为 ^^^ 部分应按其类型匹配。为什么 return 类型的 <$> 在视觉上与签名中的 <*> 输入类型不匹配?

我在这里想念什么?谢谢。

确实匹配,但是(<$>)(<*>)函数的fab是变量,变量不一样每次使用该函数时的变量。

因此,将函数定义为更有意义:

(<$>) :: Functor f     => (a -> b)   -> f a -> f b
(<*>) :: Applicative g => g (c -> d) -> g c -> g d

所以这意味着 ^@ 确实匹配:

((/) <$> Just 5) <*> Just 2
^^^^^^^^^^^^^^^^     @@@@@@

(<$>) :: Functor f     => (a -> b)   -> f a -> f b
                                               ^^^
(<*>) :: Applicative g => g (c -> d) -> g c -> g d
                          ^^^^^^^^^^    @@@

所以我们知道 (/) <$> Just 5 的类型是 f bg (c -> d),而 Just 2 的类型是 g c。由于 Just 2 的类型为 Just 2 :: Num n => Maybe n,因此这意味着 g ~ Maybec ~ n(此处 x ~ y 表示 xy 是同类型)。此外,我们可以推导出 f b ~ g (c -> d),因此 f ~ Maybe,以及 b ~ (c -> d).

我们可以进一步分析(/) <$> Just 5表达式。我们知道 Just 5 的类型是 Num m => Maybe m,所以这意味着 a ~ m。函数 (/) 的类型为 (/) :: Fractional k => k -> k -> k,因此这意味着 a ~ b ~ k ~ m,因此我们知道 (/) <$> Just 5 的类型为 (/) <$> Just 5 :: (Num m, Fractional m) => Maybe (m -> m),或者更简洁的 (/) <$> Just 5 :: Fractional m => Maybe (m -> m) ](Fractional m 表示 Num m)。

因为我们已经发现 b ~ (c -> d),所以这意味着 m ~ c ~ d,因此表达式的类型是:((/) <$> Just 5) <*> Just 2 :: Fractional m => Maybe m.