Skip to content

Instantly share code, notes, and snippets.

@siraben
Created June 2, 2020 13:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save siraben/f27601c60b3af402f8bec07d2a401e1b to your computer and use it in GitHub Desktop.
Save siraben/f27601c60b3af402f8bec07d2a401e1b to your computer and use it in GitHub Desktop.
Monoidal functors and applicatives
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE FlexibleInstances #-}
-- Tuesday, June 02, 2020
-- Monoidial functors and Applicatives
import Prelude hiding (Applicative(..), (**))
-- Lax monoidial functors
-- Laws:
-- Identity: unit ** x ~= x ** unit ~= unit
-- Associativity: u ** (v ** w) ~= (u ** v) ** w
class Functor f => Monoidal f where
unit :: f ()
(**) :: f a -> f b -> f (a,b)
-- Applicative functors
-- Identity: p ure id <*> v = v
-- Homomorphism: pure f <*> pure x = pure (f x)
-- Interchange: u <*> pure y = pure ($ y) <*> u
-- Composition: u <*> (v <*> w) = pure (.) <*> u <*> v <*> w
class Functor f => Applicative f where
pure :: a -> f a
(<*>) :: f (a -> b) -> f a -> f b
infixl 4 <*>
-- Proof that we can implement pure and (<*>) in terms of unit and
-- (**), and vice versa
instance (Functor f, Monoidal f) => Applicative f where
pure x = fmap (const x) unit
f <*> x = fmap (uncurry ($)) (f ** x)
instance (Functor f, Applicative f) => Monoidal f where
unit = pure ()
fa ** fb = (,) <$> fa <*> fb
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment