为什么 f <$> g <$> x 等同于 (f . g) <$> x 尽管 <$> 不是右结合的?

Why is f <$> g <$> x equivalent to (f . g) <$> x although <$> is not right-associative?

为什么 f <$> g <$> x 等同于 (f . g) <$> x 尽管 <$> 不是右结合的?

(这种等价在 a popular idiom 和普通 $ 中有效,但目前 $ 是右结合的!)

<*><$> 具有相同的结合性和优先级,但表现不同!

示例:

Prelude Control.Applicative> (show . show) <$> Just 3
Just "\"3\""
Prelude Control.Applicative> show <$> show <$> Just 3
Just "\"3\""
Prelude Control.Applicative> pure show <*> pure show <*> Just 3

<interactive>:12:6:
    Couldn't match type `[Char]' with `a0 -> b0'
    Expected type: (a1 -> String) -> a0 -> b0
      Actual type: (a1 -> String) -> String
    In the first argument of `pure', namely `show'
    In the first argument of `(<*>)', namely `pure show'
    In the first argument of `(<*>)', namely `pure show <*> pure show'
Prelude Control.Applicative> 
Prelude Control.Applicative> :i (<$>)
(<$>) :: Functor f => (a -> b) -> f a -> f b
    -- Defined in `Data.Functor'
infixl 4 <$>
Prelude Control.Applicative> :i (<*>)
class Functor f => Applicative f where
  ...
  (<*>) :: f (a -> b) -> f a -> f b
  ...
    -- Defined in `Control.Applicative'
infixl 4 <*>
Prelude Control.Applicative> 

根据 <$> 的定义,我预计 show <$> show <$> Just 3 也会失败。

Why is f <$> g <$> x equivalent to (f . g) <$> x?

这与其说是一个仿函数,不如说是一个 Haskell 的东西。它起作用的原因是函数是函子。两个 <$> 运算符在不同的函子中工作!

f <$> g 实际上 f . g 相同,所以你问的等价性比 f <$> (g <$> x) ≡ f . g <$> x 更微不足道.