How arbitrary is the “ap” implementation for monads?

前端 未结 2 1232
小蘑菇
小蘑菇 2021-01-04 01:17

I am currently studying the bonds between monad and applicative functors.

I see two implementation for ap:

ap m1 m2 = do { f <- m1 ; x <- m2 ;          


        
2条回答
  •  心在旅途
    2021-01-04 02:07

    Let's start with the obvious fact: such a definition for <*> violates the ap-law in the sense that <*> should ap, where ap is the one defined in the Monad class, i.e. the first one you posted.

    Trivialities aside, as far as I can see, the other applicative laws should hold.

    More concretely, let's focus on the composition law you mentioned. Your "reversed" ap

    (<**>) m1 m2 = do { x <- m2 ; f <- m1 ; return (f x) }
    

    can also be defined as

    (<**>) m1 m2 = pure (flip ($)) <*> m2 <*> m1
    

    where <*> is the "regular" ap.

    This means that, for instance,

    u <**> (v <**> w) =
      { def. <**> }
    pure (flip ($)) <*> (v <**> w) <*> u =
      { def. <**> }
    pure (flip ($)) <*> (pure (flip ($)) <*> w <*> v) <*> u =
      { composition law }
    pure (.) <*> pure (flip ($)) <*> (pure (flip ($)) <*> w) <*> v <*> u =
      { homomorphism law }
    pure ((.) (flip ($))) <*> (pure (flip ($)) <*> w) <*> v <*> u =
      { composition law }
    pure (.) <*> pure ((.) (flip ($))) <*> pure (flip ($)) <*> w <*> v <*> u =
      { homomorphism law (x2)}
    pure ((.) ((.) (flip ($))) (flip ($))) <*> w <*> v <*> u =
      { beta reduction (several) }
    pure (\x f g -> g (f x)) <*> w <*> v <*> u
    

    (I hope I got everything OK)

    Try doing something similar to the left hand side.

    pure (.) <**> u <**> v <**> w = ...
    

提交回复
热议问题