spectacle-1.0.0: src/Language/Spectacle/Specification/Variable.hs
{-# LANGUAGE PartialTypeSignatures #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UndecidableInstances #-}
-- |
--
-- @since 1.0.0
module Language.Spectacle.Specification.Variable
( -- * Syntax
Var ((:=)),
type (:.) ((:.)),
-- * Variable Constraints
HasVars,
type VarCtxt,
runInitActions,
runInitStates,
)
where
import Control.Applicative (Applicative (liftA2))
import Data.Hashable (Hashable)
import Data.Kind (Type)
import GHC.TypeLits (Symbol)
import Data.Type.List (type (++))
import Data.Type.Rec (Ascribe, HasDict, Name, Rec, RecF (ConF, NilF), pattern Con, pattern Nil, type (#))
import qualified Data.Type.Rec as Rec
import Data.World (World, makeWorld)
import Language.Spectacle.Lang (Lang, runLang)
import Language.Spectacle.Syntax.NonDet (NonDet, runNonDetA)
infixr 5 :.
-- ---------------------------------------------------------------------------------------------------------------------
data Var :: Symbol -> Type -> Type where
(:=) :: Name s -> Lang '[] '[NonDet] a -> Var s a
data (:.) :: Type -> Type -> Type where
(:.) :: a -> b -> a :. b
class HasVars a where
type VarCtxt a :: [Ascribe Symbol Type]
runInitActions :: VarCtxt a ~ ctxt => a -> RecF (Lang '[] '[NonDet]) ctxt
-- | @since 1.0.0
instance (HasVars a, HasVars b) => HasVars (a :. b) where
type VarCtxt (a :. b) = VarCtxt a ++ VarCtxt b
runInitActions (xs :. ys) = Rec.concatF (runInitActions xs) (runInitActions ys)
{-# INLINE runInitActions #-}
-- | @since 1.0.0
instance HasVars (Var var ty) where
type VarCtxt (Var var ty) = (var # ty) ': '[]
runInitActions (name := act) = ConF name act NilF
{-# INLINE runInitActions #-}
runInitStates :: forall vars ctx. (HasVars vars, HasDict Hashable ctx, VarCtxt vars ~ ctx) => vars -> [World ctx]
runInitStates vs = map makeWorld (go acts)
where
go :: RecF [] ctx' -> [Rec ctx']
go NilF = [Nil]
go (ConF nm xs rs) = liftA2 (Con nm) xs (go rs)
runner :: Name s -> Lang ctx' '[NonDet] a -> [a]
runner _ = runLang . runNonDetA @[]
acts :: RecF [] ctx
acts = Rec.mapF runner (runInitActions vs)