summaryrefslogtreecommitdiff
path: root/events/src/Events/Spec/Types.hs
blob: c7fd058eec3ff12c40fefa8e6bdc95babde84462 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
{-# LANGUAGE GADTs, DataKinds, PolyKinds, TypeOperators, KindSignatures, TypeFamilies, ExplicitNamespaces #-}

module Events.Spec.Types
  ( Expr(..)
  , Val(..)
  , Spec
  , Cmnd(..)
  , Elem(..)
  , Length(..)
  , type (++)(..)
  , module Events.Types
  ) where

import Events.Types

-- | A functional language reminiscent of typed lambda calculus with monadic
-- side-effects and foreign primitives
data Expr :: (* -> *) -> [*] -> * -> * where
  EVal :: Val m a -> Expr m ctx a
  EPri :: (Val m a -> Expr m ctx b) -> Expr m (a ': ctx) b
  EVar :: Elem a ctx -> Expr m ctx a
  ELam :: Expr m (arg ': ctx) res -> Expr m ctx (arg -> res)
  EApp :: Expr m ctx (arg -> a) -> Expr m ctx arg -> Expr m ctx a

type family Val m a where
  Val m (a -> b) = Expr m '[a] b
  Val m a        = m a

type Spec m = Expr (Eval m) '[] Cmnd

data Cmnd = COverride Object
          | COccurs Bool
          | CNop
          deriving (Show)

data Elem :: a -> [a] -> * where
  EZ :: Elem x (x ': xs)
  ES :: Elem x xs -> Elem x (y ': xs)

data Length :: [a] -> * where
  LZ :: Length '[]
  LS :: Length xs -> Length (x ': xs)

type family (xs :: [a]) ++ (ys :: [a]) :: [a] where
  '[]       ++ ys = ys
  (x ': xs) ++ ys = x ': (xs ++ ys)
infixr 5 ++