简体   繁体   中英

Applicative functors as monoidal functors

As mentioned in Hackage for Applicative Functors , they are strong lax monoidal functors. So why doesn't their definition in Haskell show it like so :

class Functor f => MonoidalApplicative f where
  mult :: f a -> f b -> f (a,b)
  unit :: a -> f a 

  starAp :: f (a -> b) -> f a -> f b
  starAp h x = fmap (uncurry ($)) (mult h x)

<*> (starAp) is easily reconstructed in terms of the multiplication and this definition looks simpler to me. For exemple, here is the Maybe instance :

instance MonoidalApplicative Maybe where
  mult (Just x) (Just y) = Just (x,y)
  mult _ _ = Nothing

  unit x = Just x

As it was mentioned in comments to your answer, there is similar story with join and >>= . When there're several semantically equivalent ways to define something it's better always to choose most efficient & pragmatic way. Haskell was designed to write code, not to prove things (though, somehow Haskell haven't still become very popular programming language unfortunately).

If starAp had default implementation almost nobody would implement it (just as it happens now with >> in Monad type class). But <*> is extremely useful operation. It is used in applicate & monadic parsers a lot ( megaparsec , attoparsec , optparse-applicative ) and I can't imagine my life w/o liftA* for joining things. And it is very important for this operation to be as efficient as possible. Implementing starAp as fmap (uncurry ($)) (mult hx) may bring hard times to inlining and optimizing things for compiler.

Moreover, representation of Applicative using mult and unit operations doesn't really solves any problems. Obviously, mult = liftA2 (,) . But your implementation with

mult (Just x) (Just y) = Just (x,y)

not fully correct. Because your implementation is not lazy enough. You will evaluate both cases when it may be enough to evaluate only one. So you still can mess up even with this simple function. Thus this representation is strictly worse.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM