{-# LANGUAGE RecordWildCards #-}
module LiveCoding.Migrate.Cell where
-- base
import Data.Data
-- syb
import Data.Generics.Aliases
-- essence-of-live-coding
import LiveCoding.Cell
import LiveCoding.Exceptions
import LiveCoding.Migrate.Migration
-- * Migrations involving sequential compositions of cells
maybeMigrateToComposition1
:: (Typeable state1', Typeable state1)
=> Composition state1 state2
-> state1'
-> Maybe (Composition state1 state2)
maybeMigrateToComposition1 (Composition (_, state2)) state1' = do
state1 <- cast state1'
return $ Composition (state1, state2)
-- | Migrate @cell1@ to @cell1 >>> cell2@.
migrationToComposition1 :: Migration
migrationToComposition1 = migrationTo2 maybeMigrateToComposition1
maybeMigrateFromComposition1
:: (Typeable state1', Typeable state1)
=> Composition state1 state2
-> Maybe state1'
maybeMigrateFromComposition1 (Composition (state1, _)) = cast state1
-- | Migrate to @cell1@ from @cell1 >>> cell2@.
migrationFromComposition1 :: Migration
migrationFromComposition1 = constMigrationFrom2 maybeMigrateFromComposition1
maybeMigrateToComposition2
:: (Typeable state2', Typeable state2)
=> Composition state1 state2
-> state2'
-> Maybe (Composition state1 state2)
maybeMigrateToComposition2 (Composition (state1, _)) state2' = do
state2 <- cast state2'
return $ Composition (state1, state2)
-- | Migrate @cell2@ to @cell1 >>> cell2@.
migrationToComposition2 :: Migration
migrationToComposition2 = migrationTo2 maybeMigrateToComposition2
maybeMigrateFromComposition2
:: (Typeable state2', Typeable state2)
=> Composition state1 state2
-> Maybe state2'
maybeMigrateFromComposition2 (Composition (_, state2)) = cast state2
-- | Migrate to @cell2@ from @cell1 >>> cell2@.
migrationFromComposition2 :: Migration
migrationFromComposition2 = constMigrationFrom2 maybeMigrateFromComposition2
-- | Combines all migrations related to composition, favouring the first argument.
migrationComposition :: Migration
migrationComposition
= migrationToComposition1
<> migrationFromComposition1
<> migrationToComposition2
<> migrationFromComposition2
-- * Migrations involving parallel compositions of cells
maybeMigrateToParallel1
:: (Typeable state1', Typeable state1)
=> Parallel state1 state2
-> state1'
-> Maybe (Parallel state1 state2)
maybeMigrateToParallel1 (Parallel (_, state2)) state1' = do
state1 <- cast state1'
return $ Parallel (state1, state2)
-- | Migrate @cell1@ to @cell1 *** cell2@.
migrationToParallel1 :: Migration
migrationToParallel1 = migrationTo2 maybeMigrateToParallel1
maybeMigrateFromParallel1
:: (Typeable state1', Typeable state1)
=> Parallel state1 state2
-> Maybe state1'
maybeMigrateFromParallel1 (Parallel (state1, _)) = cast state1
-- | Migrate to @cell1@ from @cell1 *** cell2@.
migrationFromParallel1 :: Migration
migrationFromParallel1 = constMigrationFrom2 maybeMigrateFromParallel1
maybeMigrateToParallel2
:: (Typeable state2', Typeable state2)
=> Parallel state1 state2
-> state2'
-> Maybe (Parallel state1 state2)
maybeMigrateToParallel2 (Parallel (state1, _)) state2' = do
state2 <- cast state2'
return $ Parallel (state1, state2)
-- | Migrate @cell2@ to @cell1 *** cell2@.
migrationToParallel2 :: Migration
migrationToParallel2 = migrationTo2 maybeMigrateToParallel2
maybeMigrateFromParallel2
:: (Typeable state2', Typeable state2)
=> Parallel state1 state2
-> Maybe state2'
maybeMigrateFromParallel2 (Parallel (_, state2)) = cast state2
-- | Migrate to @cell2@ from @cell1 *** cell2@.
migrationFromParallel2 :: Migration
migrationFromParallel2 = constMigrationFrom2 maybeMigrateFromParallel2
-- | Combines all migrations related to parallel composition, favouring the first argument.
migrationParallel :: Migration
migrationParallel
= migrationToParallel1
<> migrationFromParallel1
<> migrationToParallel2
<> migrationFromParallel2
-- * Migration involving 'ArrowChoice'
maybeMigrateToChoice1
:: (Typeable stateLeft', Typeable stateLeft)
=> Choice stateLeft stateRight
-> stateLeft'
-> Maybe (Choice stateLeft stateRight)
maybeMigrateToChoice1 Choice { .. } choiceLeft' = do
choiceLeft <- cast choiceLeft'
return Choice { .. }
-- | Migrate @cell1@ to @cell1 ||| cell2@.
migrationToChoice1 :: Migration
migrationToChoice1 = migrationTo2 maybeMigrateToChoice1
maybeMigrateFromChoice1
:: (Typeable stateLeft', Typeable stateLeft)
=> Choice stateLeft stateRight
-> Maybe stateLeft'
maybeMigrateFromChoice1 Choice { .. } = cast choiceLeft
-- | Migrate to @cell1@ from @cell1 ||| cell2@.
migrationFromChoice1 :: Migration
migrationFromChoice1 = constMigrationFrom2 maybeMigrateFromChoice1
maybeMigrateToChoice2
:: (Typeable stateRight', Typeable stateRight)
=> Choice stateLeft stateRight
-> stateRight'
-> Maybe (Choice stateLeft stateRight)
maybeMigrateToChoice2 Choice { .. } choiceRight' = do
choiceRight <- cast choiceRight'
return Choice { .. }
-- | Migrate @cell2@ to @cell1 ||| cell2@.
migrationToChoice2 :: Migration
migrationToChoice2 = migrationTo2 maybeMigrateToChoice2
maybeMigrateFromChoice2
:: (Typeable stateRight', Typeable stateRight)
=> Choice stateLeft stateRight
-> Maybe stateRight'
maybeMigrateFromChoice2 Choice { .. } = cast choiceRight
-- | Migrate to @cell2@ from @cell1 ||| cell2@.
migrationFromChoice2 :: Migration
migrationFromChoice2 = constMigrationFrom2 maybeMigrateFromChoice2
-- | Combines all migrations related to choice.
migrationChoice :: Migration
migrationChoice
= migrationToChoice1
<> migrationFromChoice1
<> migrationToChoice2
<> migrationFromChoice2
-- * Control flow
maybeMigrateToExceptState
:: (Typeable state, Typeable state')
=> ExceptState state e
-> state'
-> Maybe (ExceptState state e)
maybeMigrateToExceptState (NotThrown _) state = NotThrown <$> cast state
maybeMigrateToExceptState (Exception e) _ = Just $ Exception e
-- | Migration from @cell2@ to @try cell1 >> safe cell2@
migrationToExceptState :: Migration
migrationToExceptState = migrationTo2 maybeMigrateToExceptState
maybeMigrateFromExceptState
:: (Typeable state, Typeable state')
=> ExceptState state e
-> Maybe state'
maybeMigrateFromExceptState (NotThrown state) = cast state
maybeMigrateFromExceptState (Exception e) = Nothing
-- | Migration from @try cell1 >> safe cell2@ to @cell2@
migrationFromExceptState :: Migration
migrationFromExceptState = constMigrationFrom2 maybeMigrateFromExceptState
-- | Combines all control flow related migrations
migrationExceptState :: Migration
migrationExceptState = migrationToExceptState <> migrationFromExceptState
-- * Overall migration
-- | Combines all 'Cell'-related migrations.
migrationCell :: Migration
migrationCell
= migrationComposition
<> migrationParallel
<> migrationChoice
<> migrationExceptState