Last active
November 11, 2019 19:48
-
-
Save chrisdone/cd3d9d77579eac216b4498beea8fc394 to your computer and use it in GitHub Desktop.
GADT monad
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{-# 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