Skip to content

Instantly share code, notes, and snippets.

@mtolly
Last active August 29, 2015 14:05
Show Gist options
  • Save mtolly/af3548cc50aa470b4483 to your computer and use it in GitHub Desktop.
Save mtolly/af3548cc50aa470b4483 to your computer and use it in GitHub Desktop.
Updated working version of "imperative Haskell" by augustss: http://augustss.blogspot.com/2007/08/programming-in-c-ummm-haskell-heres.html
{-# LANGUAGE Haskell2010, GADTs, Rank2Types, FlexibleInstances #-}
module Main where
import Data.IORef
import Control.Applicative
data X v a where
E :: IO a -> X RValue a
V :: IO a -> (a -> IO ()) -> X v a
data LValue
data RValue
type V a = X LValue a
type E a = X RValue a
newtype Var a = Var (forall v. X v a)
instance (Num a) => Num (E a) where
fromInteger = E . return . fromInteger
x + y = E $ liftA2 (+) (get x) (get y)
x - y = E $ liftA2 (-) (get x) (get y)
x * y = E $ liftA2 (*) (get x) (get y)
abs = E . fmap abs . get
signum = E . fmap signum . get
get :: E a -> IO a
get (E t ) = t
get (V t _) = t
auto :: E a -> IO (Var a)
auto x = do
x' <- get x
r <- newIORef x'
return $ Var $ V (readIORef r) (writeIORef r)
($=) :: V a -> E a -> IO ()
V _ setter $= y = do
y' <- get y
setter y'
infixr 0 $=
-- This is the same as ($), which means you can do "var $= fun $ thing"
main :: IO ()
main = do
Var x <- auto 5
x $= x * 2
x $= x + 1
get x >>= print
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment