Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a standard name or implementation of the "purely applicative Either"?

I frequently find use for what I call the "purely applicative Either", i.e. Either with the Applicative instance available so long as we don't implement a Monad instance as well.

newtype AEither e a = AEither { unAEither :: Either e a }
  deriving Functor

-- technically we only need Semigroup
instance Monoid e => Applicative (AEither e) where
  pure a = AEither (pure a)
  AEither e1 <*> AEither e2 = AEither (combine e1 e2) where
    combine (Right f) (Right a) = Right (f a)
    combine (Left m1) (Left m2) = Left (m1 <> m2)
    combine (Left m ) _         = Left m
    combine _         (Left m ) = Left m

It's a really useful Applicative as it provides a more powerful notion of "summarization of error" than Either's Monad instance can do. To that end, I find myself implementing it over-and-over again.

Is there a standard instance somewhere? Is there even a standard name?

like image 912
J. Abrahamson Avatar asked Mar 08 '14 02:03

J. Abrahamson


People also ask

What is pure applicative?

The function pure is the second method required by the Applicative type class. The pure method is a useful helper function for taking an ordinary value or function and putting it into a context. The best way to understand pure is to play around with it in GHCi.

Could you comfortably explain the difference between a monad and an applicative functor?

Functors apply a function to a wrapped value: Applicatives apply a wrapped function to a wrapped value: Monads apply a function that returns a wrapped value to a wrapped value. Monads have a function >>= (pronounced "bind") to do this.


1 Answers

This looks pretty similar to the AccValidation type in the validation package: http://hackage.haskell.org/package/validation-0.3.1/docs/Data-Validation.html

Edit:

In particular the following instance declaration:

instance Semigroup err => Apply (AccValidation err) where
  AccFailure e1 <.> AccFailure e2 =
    AccFailure (e1 <> e2)
  AccFailure e1 <.> AccSuccess _  =
    AccFailure e1
  AccSuccess _  <.> AccFailure e2 =
    AccFailure e2
  AccSuccess f  <.> AccSuccess a  =
    AccSuccess (f a)
like image 91
unfoldr Avatar answered Oct 29 '22 16:10

unfoldr