Last active
August 29, 2015 14:22
-
-
Save beala/9e1f553f8fb8d2d061c6 to your computer and use it in GitHub Desktop.
Using tardis (forwards and backwards state monad) to implement a toy language that lets you dereference a var before assigning to it.
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 RecursiveDo #-} | |
import Control.Monad.Tardis | |
import qualified Data.Map as M | |
-- Language that lets you dereference variable names and assign to names, | |
-- but assignment must happen *after* dereference! | |
data ReverseLang = Assign String Int -- Assign to a name. | |
| Var String -- Dereference a name. | |
-- A program is a list of dereferences and assignments. | |
type Program = [ReverseLang] | |
program :: Program | |
program = [ Var "a" -- Dereference "a" | |
, Var "b" | |
, Var "c" | |
, Assign "c" 3 | |
, Var "a" | |
, Assign "a" 1 -- Assign to "a" | |
, Assign "b" 2 | |
] | |
-- Sum all the dereferenced variables in a program. | |
sumProg :: Program -> Tardis (M.Map String Int) (Maybe Int) (Maybe Int) | |
sumProg ((Var s) : vs) = do | |
acc <- getPast | |
varMap <- getFuture | |
sendFuture $ do -- Propogate the accumulated sum forward. | |
a <- acc | |
a' <- M.lookup s varMap | |
return $ a + a' | |
sumProg vs | |
sumProg ((Assign n i) : vs) = do | |
rec -- Propogate the assignments backwards in time. | |
sendPast (M.insert n i varMap) | |
varMap <- getFuture | |
sumProg vs | |
sumProg [] = getPast | |
main :: IO () | |
main = do | |
print $ evalTardis (sumProg program) (M.empty, Just 0) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Tardis package: https://hackage.haskell.org/package/tardis-0.3.0.0