Skip to content

Instantly share code, notes, and snippets.

@bollu
Last active January 8, 2016 07:55
Show Gist options
  • Select an option

  • Save bollu/f5a8e4c779a1e039d80b to your computer and use it in GitHub Desktop.

Select an option

Save bollu/f5a8e4c779a1e039d80b to your computer and use it in GitHub Desktop.
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE UndecidableInstances #-}
module Main where
data Free f a = Pure a | Branch (f (Free f a))
deriving instance (Show a, Show (f (Free f a))) => Show (Free f a)
instance Functor f => Functor (Free f) where
--fmap :: (a -> b) -> Free f a -> Free f b
fmap fn (Pure a) = Pure (fn a)
-- fmap :: (a -> b) Branch (f (Free f a))
fmap fn (Branch b) = Branch (((fmap . fmap) fn) b)
join :: Functor f => Free f (Free f a) -> Free f a
join (Pure a) = a
join (Branch x) = Branch (fmap join x)
instance Functor f => Monad (Free f) where
return a = Pure a
(>>=) x f = join (fmap f x)
instance Functor f => Applicative (Free f) where
pure = return
--(<*>) :: f (a -> b) ->f a -> fb
(<*>) freefn freea = do fn <- freefn; a <- freea; return $ fn a
type Key = String
type Value = String
data DSL next = Get Key (Value -> next) |
Set Key Value next |
Done
instance Functor DSL where
--fmap :: (a -> b) -> DSL a -> DSL b
fmap f (Get key user) = Get key (f . user)
fmap f (Set key value next) = Set key value (f next)
fmap f Done = Done
--Branch (DSL (Pure Value))
getLift :: Key -> Free DSL Value
getLift key = Branch (Get key (\value -> Pure value)) -- is this right?
setLift :: Key -> Value -> Free DSL ()
setLift key value = Branch ((Set key value (Pure ())))
doneLift :: Free DSL a
doneLift = Branch Done
run :: Free DSL a -> IO ()
run (Pure a) = return ()
run (Branch (Set key value f)) = (putStrLn ("setting: " ++ key ++ " |to: " ++ value)) >> run f
run (Branch (Get key user)) = (putStrLn ("getting: " ++ key)) >> run (user ("value-for-key-" ++ key))
run (Branch Done) = print "all done!"
simpleTest = do
bolluVal <- getLift "bollu-key"
setLift bolluVal "newVal"
doneLift
main :: IO ()
main = run simpleTest
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment