{- | Run a cell at a fixed integer multiple speed. The general approach is to take an existing cell (the "inner" cell) and produce a new cell (the "outer" cell) that will accept several copies of the input. The inner cell is stepped for each input. -} {-# LANGUAGE NamedFieldPuns #-} {-# LANGUAGE RecordWildCards #-} module LiveCoding.Cell.Resample where -- base import Control.Arrow import Data.Maybe import GHC.TypeNats -- vector-sized import Data.Vector.Sized -- essence-of-live-coding import LiveCoding.Cell -- | Execute the inner cell for n steps per outer step. resample :: (Monad m, KnownNat n) => Cell m a b -> Cell m (Vector n a) (Vector n b) resample cell = arr toList >>> resampleList cell >>> arr (fromList >>> fromJust) -- | Execute the cell for as many steps as the input list is long. resampleList :: Monad m => Cell m a b -> Cell m [a] [b] resampleList Cell { cellState, cellStep = singleStep } = Cell { .. } where cellStep s [] = return ([], s) cellStep s (a : as) = do (b , s' ) <- singleStep s a (bs, s'') <- cellStep s' as return (b : bs, s'') resampleMaybe :: Monad m => Cell m a b -> Cell m (Maybe a) (Maybe b) resampleMaybe cell = arr maybeToList >>> resampleList cell >>> arr listToMaybe