Skip to content

Instantly share code, notes, and snippets.

@chrisdone
Last active November 11, 2019 19:48
Show Gist options
  • Save chrisdone/cd3d9d77579eac216b4498beea8fc394 to your computer and use it in GitHub Desktop.
Save chrisdone/cd3d9d77579eac216b4498beea8fc394 to your computer and use it in GitHub Desktop.
GADT monad
{-# LANGUAGE GADTs, LambdaCase #-}
import Control.Monad
-- Model the problem with a simple GADT:
data Foo a where
GetInput :: Foo String
WriteOutput :: String -> Foo ()
Pure :: a -> Foo a
Bind :: Foo a -> (a -> Foo b) -> Foo b
-- Implement instances trivially:
instance Monad Foo where (>>=) = Bind; return = Pure
instance Applicative Foo where (<*>) = ap; pure = return
instance Functor Foo where fmap = liftM
-- Write an interpreter for the GADT:
interpretFoo :: Foo a -> IO a
interpretFoo =
\case
GetInput -> getLine
WriteOutput s -> putStrLn s
Pure a -> pure a
Bind m f -> interpretFoo m >>= interpretFoo . f
-- You can write other, pure, interpreters, or anything else.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment