适用函子。<*>和<$>的类型签名详细

Max*_*Max 2 haskell applicative

我们有签名:

(<$>) :: Functor f     =>   (a -> b) -> f a -> f b
(<*>) :: Applicative f => f (a -> b) -> f a -> f b 
Run Code Online (Sandbox Code Playgroud)

让我们玩一下:

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

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

( Just (\x -> 5/x ) ) <*> Just 2
=> Just 2.5
Run Code Online (Sandbox Code Playgroud)

题:

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

(<$>) :: Functor f     =>   (a -> b) -> f a -> f b
                                               ^^^
(<*>) :: Applicative f => f (a -> b) -> f a -> f b
                          ^^^^^^^^^^    @@@
Run Code Online (Sandbox Code Playgroud)

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

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

Wil*_*sem 6

它不匹配,但是fab(<$>)(<*>)函数是变量,并在每次使用该功能时的变量是不同的变量。

因此,将函数定义为:

(<$>) :: Functor f     => (a -> b)   -> f a -> f b
(<*>) :: Applicative g => g (c -> d) -> g c -> g d
Run Code Online (Sandbox Code Playgroud)

因此,意味着^@确实匹配为:

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

(<$>) :: Functor f     => (a -> b)   -> f a -> f b
                                               ^^^
(<*>) :: Applicative g => g (c -> d) -> g c -> g d
                          ^^^^^^^^^^    @@@
Run Code Online (Sandbox Code Playgroud)

因此,我们知道(/) <$> Just 5is 的类型为f band g (c -> d),而Just 2has的类型g c。由于Just 2具有type Just 2 :: Num n => Maybe n,因此表示g ~ Maybeand c ~ n(此处x ~ y表示xand y是同一类型)。此外,我们可以得出f b ~ g (c -> d),因此f ~ Maybeb ~ (c -> d)

我们可以进一步分析该(/) <$> Just 5表达。我们知道那Just 5有类型Num m => Maybe m,所以就意味着a ~ m。该函数(/)具有type (/) :: Fractional k => k -> k -> k,因此表示具有a ~ b ~ k ~ m,因此我们知道其(/) <$> Just 5具有type (/) <$> Just 5 :: (Num m, Fractional m) => Maybe (m -> m),或者较不冗长(/) <$> Just 5 :: Fractional m => Maybe (m -> m)(a Fractional m暗含Num m)。

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