Skip to content

Instantly share code, notes, and snippets.

@justanotherdot
Last active August 4, 2017 05:57
Show Gist options
  • Save justanotherdot/0949b29ba73cbeb61b29ee8613fbcfb9 to your computer and use it in GitHub Desktop.
Save justanotherdot/0949b29ba73cbeb61b29ee8613fbcfb9 to your computer and use it in GitHub Desktop.
Composition of Applicative vs. Monads
-- Source https://stackoverflow.com/a/13209294/2748415
{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE TypeOperators #-}
-- Thud just goes 'Thud'.
data Thud a = Thud
deriving (Show, Functor)
instance Applicative Thud where
pure _ = Thud
_ <*> _ = Thud
instance Monad Thud where
return _ = Thud
_ >>= _ = Thud
-- Flip is the Writer of Bool.
data Flip x = Flip Bool x
deriving (Show, Functor)
instance Applicative Flip where
pure = return
(Flip b0 f) <*> (Flip b1 x) = Flip (not $ b0 && b1) (f x)
instance Monad Flip where
return = Flip False
Flip False x >>= f = f x
Flip True x >>= f = Flip (not b) y where Flip b y = f x
-- Introduce composition.
newtype (:.:) f g x = C (f (g x))
deriving (Show, Functor)
instance Applicative (Flip :.: Thud) where
pure _ = C (Flip True Thud)
C (Flip b0 _) <*> C (Flip b1 x) = C (Flip (not $ b0 && b1) Thud)
-- We cannot write the below instance.
--
-- The reason being that `join . return = id` will fail
-- as the given hole in `return` means we can't depend on
-- what `x` may be, so it must be a constant.
--
-- One can look at the Applicative instance for a concrete
-- example of `(Flip :.: Thud)` being a constant.
{-
instance Monad (Flip :.: Thud) where
return x = C (Flip _ Thud)
...
-}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment