Last active
May 29, 2018 18:05
-
-
Save KirinDave/7e8ed107c372e197e181ee716b34753e to your computer and use it in GitHub Desktop.
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 DeriveFunctor, FlexibleInstances #-} | |
module Lib where | |
newtype Mu f = Mu (f (Mu f)) | |
data ArithF f = | |
ALit Int | | |
AAdd f f | | |
ASub f f deriving Functor | |
lit :: Int -> Arith | |
lit i = Mu $ ALit i | |
add :: Arith -> Arith -> Arith | |
add x y = Mu $ AAdd x y | |
sub :: Arith -> Arith -> Arith | |
sub x y = Mu $ ASub x y | |
cata :: Functor f => (f a -> a) -> Mu f -> a | |
cata f (Mu g) = f (fmap (cata f) g) | |
type Arith = Mu ArithF | |
type Alg f a = f a -> a | |
-- This is why we need FlexibleInstances | |
instance Show (Mu ArithF) where | |
show = cata printer | |
printer :: Alg ArithF String | |
printer (ALit i) = show i | |
printer (AAdd l r) = "(" ++ l ++ " + " ++ r ++ ")" | |
printer (ASub l r) = "(" ++ l ++ " - " ++ r ++ ")" | |
interpreter :: Alg ArithF Int | |
interpreter (ALit i) = i | |
interpreter (AAdd l r) = l + r | |
interpreter (ASub l r) = l - r | |
keep :: Alg ArithF Arith | |
keep = Mu | |
(<+>) :: Functor f => Alg f a -> Alg f b -> Alg f (a,b) | |
c1 <+> c2 = \f -> (c1 $ fmap fst f, | |
c2 $ fmap snd f) | |
eval :: Arith -> (Int, String) | |
eval = cata (interpreter <+> printer) | |
annotated :: Arith -> (Int, Arith) | |
annotated = cata (interpreter <+> keep) | |
full :: Arith -> (Int, (String, Arith)) | |
full = cata (interpreter <+> (printer <+> keep)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment