indigo-0.4: src/Indigo/Internal/SIS.hs
-- SPDX-FileCopyrightText: 2020 Tocqueville Group
--
-- SPDX-License-Identifier: LicenseRef-MIT-TQ
module Indigo.Internal.SIS
( SomeIndigoState (..)
, SomeGenCode (..)
, toSIS
, runSIS
, thenSIS
, overSIS
) where
import Indigo.Prelude
import Indigo.Internal.State
-- | 'GenCode' with hidden output stack
data SomeGenCode inp where
SomeGenCode :: GenCode inp out -> SomeGenCode inp
-- | 'IndigoState' with hidden output stack,
-- necessary to generate typed Lorentz code from untyped Indigo frontend.
newtype SomeIndigoState inp = SomeIndigoState
{ unSIS :: MetaData inp -> SomeGenCode inp
}
-- | To run 'SomeIndigoState' you need to pass an handler of 'GenCode' with any
-- output stack and initial 'MetaData'.
runSIS :: SomeIndigoState inp -> MetaData inp -> (forall out . GenCode inp out -> r) -> r
runSIS (SomeIndigoState act) md f = case act md of
SomeGenCode gc -> f gc
-- | Convert 'IndigoState' to 'SomeIndigoState'
toSIS :: IndigoState inp out -> SomeIndigoState inp
toSIS is = SomeIndigoState $ \md -> SomeGenCode $ runIndigoState is md
-- | Similar to a @>>@ for 'SomeIndigoState'.
thenSIS :: SomeIndigoState inp -> (forall out . SomeIndigoState out) -> SomeIndigoState inp
thenSIS m f = SomeIndigoState $ \md ->
case unSIS m md of
(SomeGenCode (GenCode st1 cd1 cl1 :: GenCode inp out)) ->
case unSIS (f @out) (replStkMd md st1) of
SomeGenCode (GenCode st2 cd2 cl2) ->
SomeGenCode (GenCode st2 (cd1 ## cd2) (cl2 ## cl1))
-- | Modify the 'GenCode' inside a 'SomeIndigoState' by passing an handler of
-- 'GenCode' that returns a 'SomeGenCode'.
-- Useful in some cases to "wrap" or update and exising 'SomeGenCode'.
overSIS
:: (forall out. GenCode inp out -> SomeGenCode inp)
-> SomeIndigoState inp
-> SomeIndigoState inp
overSIS f si = SomeIndigoState $ \md -> runSIS si md f