Change the program, keep the state! https://github.com/turion/essence-of-live-coding
Manuel Bärenz
runLiveProgram :: LiveProgram m -> m ()
runLiveProgram LiveProgram { .. } = do
liveState' <- liveStep liveState
runLiveProgram LiveProgram { liveState = liveState', .. }
Polymorphic in m
:
IO
)Greetings, number 1
Greetings, number 2
HI #3
server greeting = LiveProgram { .. } where
liveState = State 1 $ read "2019-07-24 19:00:00 UTC"
liveStep State { .. } = do
putStrLn $ greeting ++ show nVisitors
lastTime <- getCurrentTime
return State { nVisitors = nVisitors + 1, .. }
…but the new state won’t type-check!
Migrating to new state should…
nVisitors
lastTime
⇒ Need old live state and new initial state
migrate :: (Data sNew, Data sOld) => sNew -> sOld -> sNew
migrate = ... -- Just some 50 lines generic code
Conversion from/to…
Small restriction: Add Data
to all states:
The migration is derived from the state type!
⇒ Add inputs and outputs to live programs!
Category
Arrow
Haskell Symposium 2016
ArrowChoice
: (Transient) control flowArrowLoop
: Recursion (but beware!)PictureM
: Retrieve events, IO, add picturesglossCell :: Cell PictureM () ()
glossCell = proc () -> do
events <- constM ask -< ()
arrM $ liftIO . print -< events
ball <- ballSim -< events
addPicture -< ballPic ball
HandlingStateT
: Handle Gloss threadThrowing and catching exceptions
Custom GHCi commands:
foreign-store
under the hood)Data
⇒ automatically generate cell state for tests“A debugger is a live program that can read and modify the state of another live program.”
instance (Arbitrary a, Show a, Testable prop)
=> Testable (Cell IO a prop) where ...
testCell :: Monad m => Cell m (Positive Int) Bool
testCell = arr getPositive >>> sumC >>> arr (>= 0)
> quickCheck testCell
+++ OK, passed 100 tests.
type StateTransition m a b s = a -> m (b, s)
data MSF m a b = MSF (StateTransition m a b (MSF m a b))
data Coalg m a b = forall s .
Coalg s (s -> StateTransition m a b s)
cellCoalgebra :: Cell m a b -> Coalg m a b
coalgebra :: MSF m a b -> Coalg m a b
finality :: Monad m => Coalg m a b -> MSF m a b
finalityC :: Monad m => Cell m a b -> MSF m a b
coalgebraC :: Data (MSF m a b) => MSF m a b -> Cell m a b