Is this a Functor or Monad?

haskell

Solution

Yes, it is a monad. The easiest way to see this is observing `Promise f a ≅ Maybe (Either f a)`, thus it's also isomorphic to the transformer equivalent which has an already-proven standard monad instance.

type Promise' f = ErrorT f Maybe

promise2Trafo :: Promise f a -> Promise' f a
promise2Trafo (PendingPromise f) = ErrorT . Just $ Left f
promise2Trafo (ResolvedPromise a) = ErrorT . Just $ Right a
promise2Trafo BrokenPromise = ErrorT Nothing

trafo2Promise :: Promise' f a -> Promise f a
trafo2Promise = ... -- straightforward inverse of `promise2Trafo`

instance Applicative Promise where
  pure = trafo2Promise . pure
  fp <*> xp = trafo2Promise $ promise2Trafo fp <*> promise2Trafo xp

and so on.

Problem

I implemented my own Promise structure in C# and wanted to test the concept in Haskell so after some severe brain workouts (still very new to this) I produced ``` data Promise f a = PendingPromise f | ResolvedPromise a | BrokenPromise deriving( Show ) class Future p where later :: (b -> c) -> p (a -> b) b -> p (a -> c) c resolve :: p (a -> b) a -> a -> p (a -> b) b instance Future Promise where later g (PendingPromise f) = PendingPromise (g . f) later g (ResolvedPromise a) = ResolvedPromise (g a) resolve (PendingPromise f) a = ResolvedPromise (f a) ``` Figuring out how to write this datatype `Promise f a` was a real headache. Anyway, the `later` method seems to be some sort of Applicative Functor and Promises are supposed to be Monads. Is it possible for me to make `Promise` an instance of some class and get this functionality instead of implementing my own class Future? Edit Thanks to @bheklilr the `later` function was proven to be `fmap` in disguise with a little redefinition of the datatype ``` data Promise a b = PendingPromise (a -> b) | ResolvedPromise b | BrokenPromise instance Functor (Promise c) where fmap f (PendingPromise g) = PendingPromise (f . g) fmap f (ResolvedPromise a) = ResolvedPromise (f a) fmap f BrokenPromise = BrokenPromise ``` Knowing that (Promise a) is a Functor, it is easier to see why is a Monad.

Original source

Related problems