Skip to content

Instantly share code, notes, and snippets.

@gergoerdi
Created November 27, 2014 11:44
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 gergoerdi/13bf90ac17079997a123 to your computer and use it in GitHub Desktop.
Save gergoerdi/13bf90ac17079997a123 to your computer and use it in GitHub Desktop.
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE ViewPatterns #-}
{-# LANGUAGE TypeSynonymInstances, FlexibleInstances #-}
{-# LANGUAGE DeriveFunctor #-}
newtype Fix f = Fix { unFix :: f (Fix f) }
data HuttonF a = IntF Int | AddF a a deriving Functor
type Hutton = Fix HuttonF
data Holey f = Holey Hole | Expr (f (Holey f))
type HuttonHole = Holey HuttonF
data Hole = Hole
class Project a where
proj :: a -> HuttonF a
class Inject a where
inj :: HuttonF a -> a
instance Inject HuttonHole where
inj = Expr
pattern I :: () => (Project a, Inject a) => Int -> a
pattern I n <- (proj -> IntF n) where
I n = inj (IntF n)
pattern Add :: () => (Project a, Inject a) => a -> a -> a
pattern Add a b <- (proj -> AddF a b) where
Add a b = inj (AddF a b)
hole :: HuttonHole
hole = Holey Hole
p4 :: HuttonHole
p4 = Add (I 5) hole
fillHole :: (Hole -> Hutton) -> HuttonHole -> Hutton
fillHole f (Holey hole) = f hole
fillHole f (Expr (IntF n)) = Fix $ IntF n
fillHole f (Expr (AddF e1 e2)) = Fix $ AddF (fillHole f e1) (fillHole f e2)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment