{-# LANGUAGE ExistentialQuantification #-}
{-# LANGUAGE RecordWildCards #-}
module Util.LiveProgramMigration where
-- transformers
import Control.Monad.Trans.RWS.Strict (RWS, runRWS)
-- QuickCheck
import Test.QuickCheck
-- essence-of-live-coding
import LiveCoding
data LiveProgramMigration a b = forall s.
LiveProgramMigration
{ liveProgram1 :: LiveProgram (RWS a b s)
, liveProgram2 :: LiveProgram (RWS a b s)
, initialState :: s
, input1 :: [a]
, input2 :: [a]
, output1 :: [b]
, output2 :: [b]
}
stepLiveProgramRWS :: Monoid b => LiveProgram (RWS a b s) -> a -> s -> (LiveProgram (RWS a b s), s, b)
stepLiveProgramRWS liveProg = runRWS (stepProgram liveProg)
stepsLiveProgramRWS :: Monoid b => LiveProgram (RWS a b s) -> s -> [a] -> (LiveProgram (RWS a b s), s, [b])
stepsLiveProgramRWS liveProg s [] = (liveProg, s, [])
stepsLiveProgramRWS liveProg s (a : as) =
let (liveProg', s', b) = stepLiveProgramRWS liveProg a s
in (liveProg', s', b : third (stepsLiveProgramRWS liveProg' s' as))
third :: (a, b, c) -> c
third (a, b, c) = c
instance (Monoid b, Eq b, Show b) => Testable (LiveProgramMigration a b) where
property LiveProgramMigration {..} =
let (liveProg', s', output1') = stepsLiveProgramRWS liveProgram1 initialState input1
liveProg2 = hotCodeSwap liveProgram2 liveProg'
(_, _, output2') = stepsLiveProgramRWS liveProg2 s' input2
in output1 === output1' .&&. output2 === output2'