diff options
| -rw-r--r-- | events/src/Events/Eval.hs | 2 | ||||
| -rw-r--r-- | events/src/Events/Spec.hs | 18 | ||||
| -rw-r--r-- | events/src/Events/Spec/Eval.hs | 38 | ||||
| -rw-r--r-- | events/src/Events/Spec/LICENSE | 29 | ||||
| -rw-r--r-- | events/src/Events/Spec/Types.hs | 32 | ||||
| -rw-r--r-- | events/src/Events/Types.hs | 20 | ||||
| -rw-r--r-- | events/src/Main.hs | 2 |
7 files changed, 125 insertions, 16 deletions
diff --git a/events/src/Events/Eval.hs b/events/src/Events/Eval.hs index 280c577..800b38d 100644 --- a/events/src/Events/Eval.hs +++ b/events/src/Events/Eval.hs | |||
| @@ -17,7 +17,7 @@ import Control.Lens | |||
| 17 | import Data.Ord (Ordering(..)) | 17 | import Data.Ord (Ordering(..)) |
| 18 | 18 | ||
| 19 | evaluate :: MonadFix m => (Maybe Object -> ReaderT EvalCtx m Bool) -> Eval m () -> m [Object] | 19 | evaluate :: MonadFix m => (Maybe Object -> ReaderT EvalCtx m Bool) -> Eval m () -> m [Object] |
| 20 | evaluate predicate x = catMaybes <$> mfix x' | 20 | evaluate predicate (unEval -> x) = catMaybes <$> mfix x' |
| 21 | where | 21 | where |
| 22 | x' = runReaderT (foldNDT predicate (preview objCtx <$> execStateT x def)) . flip (set ctxEvents) def . catMaybes | 22 | x' = runReaderT (foldNDT predicate (preview objCtx <$> execStateT x def)) . flip (set ctxEvents) def . catMaybes |
| 23 | 23 | ||
diff --git a/events/src/Events/Spec.hs b/events/src/Events/Spec.hs index 2af3446..e098886 100644 --- a/events/src/Events/Spec.hs +++ b/events/src/Events/Spec.hs | |||
| @@ -1,11 +1,13 @@ | |||
| 1 | {-# LANGUAGE GADTs #-} | 1 | {-# LANGUAGE GADTs, DataKinds, TypeOperators #-} |
| 2 | 2 | ||
| 3 | module Events.Spec | 3 | module Events.Spec |
| 4 | ( interpret | 4 | ( interpret |
| 5 | , Spec, Cmnd(..), Expr(..) | 5 | , Spec, Cmnd(..), Expr(..), Elem(..) |
| 6 | ) where | 6 | ) where |
| 7 | 7 | ||
| 8 | import Events.Types | 8 | import Events.Types |
| 9 | import Events.Spec.Types | ||
| 10 | import Events.Spec.Eval | ||
| 9 | 11 | ||
| 10 | import Control.Monad ((<=<)) | 12 | import Control.Monad ((<=<)) |
| 11 | import Control.Monad.IO.Class | 13 | import Control.Monad.IO.Class |
| @@ -17,21 +19,15 @@ import Control.Lens | |||
| 17 | 19 | ||
| 18 | import Debug.Trace | 20 | import Debug.Trace |
| 19 | 21 | ||
| 20 | type Spec = [Expr Cmnd] -- most significant last | 22 | type Spec m = Expr (Eval m) '[] Cmnd -- most significant last |
| 21 | 23 | ||
| 22 | data Cmnd = COverride Object | 24 | data Cmnd = COverride Object |
| 23 | | COccurs Bool | 25 | | COccurs Bool |
| 24 | | CNop | 26 | | CNop |
| 25 | deriving (Show) | 27 | deriving (Show) |
| 26 | 28 | ||
| 27 | data Expr a where | 29 | interpret :: MonadIO m => Spec m -> Eval m () |
| 28 | ELit :: a -> Expr a | 30 | interpret = join . fmap interpretCmnd . evalExpr |
| 29 | |||
| 30 | interpret :: MonadIO m => Spec -> Eval m () | ||
| 31 | interpret = mapM_ $ interpretCmnd <=< interpretExpr | ||
| 32 | |||
| 33 | interpretExpr :: MonadIO m => Expr Cmnd -> m Cmnd | ||
| 34 | interpretExpr (ELit a) = return a | ||
| 35 | 31 | ||
| 36 | interpretCmnd :: MonadIO m => Cmnd -> Eval m () | 32 | interpretCmnd :: MonadIO m => Cmnd -> Eval m () |
| 37 | interpretCmnd (COverride obj) = objPayload ?= obj | 33 | interpretCmnd (COverride obj) = objPayload ?= obj |
diff --git a/events/src/Events/Spec/Eval.hs b/events/src/Events/Spec/Eval.hs new file mode 100644 index 0000000..3a23e0b --- /dev/null +++ b/events/src/Events/Spec/Eval.hs | |||
| @@ -0,0 +1,38 @@ | |||
| 1 | {-# LANGUAGE GADTs, DataKinds, TypeOperators, RankNTypes, ScopedTypeVariables #-} | ||
| 2 | |||
| 3 | module Events.Spec.Eval | ||
| 4 | ( evalExpr | ||
| 5 | ) where | ||
| 6 | |||
| 7 | import Events.Spec.Types | ||
| 8 | |||
| 9 | shift :: forall m ts2 t x. Expr m ts2 x -> Expr m (t ': ts2) x | ||
| 10 | shift = shift' LZ | ||
| 11 | where | ||
| 12 | -- shift' :: forall ts1 ts2 t x. Length ts1 -> Expr (ts1 ++ ts2) x -> Expr (ts1 ++ t ': ts2) x | ||
| 13 | shift' :: forall ts1 x. Length ts1 -> Expr m (ts1 ++ ts2) x -> Expr m (ts1 ++ t ': ts2) x | ||
| 14 | shift' _ (ELit x) = ELit x | ||
| 15 | shift' l (EVar v) = EVar $ shiftElem l v | ||
| 16 | shift' l (ELam b) = ELam $ shift' (LS l) b | ||
| 17 | shift' l (EApp f x) = EApp (shift' l f) (shift' l x) | ||
| 18 | |||
| 19 | shiftElem :: forall ts1 u. Length ts1 -> Elem u (ts1 ++ ts2) -> Elem u (ts1 ++ t ': ts2) | ||
| 20 | shiftElem LZ e = ES e | ||
| 21 | shiftElem (LS _) EZ = EZ | ||
| 22 | shiftElem (LS l) (ES e) = ES $ shiftElem l e | ||
| 23 | |||
| 24 | |||
| 25 | beta = flip beta' LZ | ||
| 26 | beta' :: forall m ts1 ts2 s t. Expr m ts2 s -> Length ts1 -> Expr m (ts1 ++ s ': ts2) t -> Expr m (ts1 ++ ts2) t | ||
| 27 | beta' _ _ (ELit x) = ELit x | ||
| 28 | beta' e LZ (EVar EZ ) = e | ||
| 29 | beta' _ LZ (EVar (ES v)) = EVar v | ||
| 30 | beta' _ (LS _) (EVar EZ ) = EVar EZ | ||
| 31 | beta' e (LS l) (EVar (ES v)) = shift $ beta' e l (EVar v) | ||
| 32 | beta' e l (ELam b) = ELam $ beta' e (LS l) b | ||
| 33 | beta' e l (EApp f a) = EApp (beta' e l f) (beta' e l a) | ||
| 34 | |||
| 35 | evalExpr :: Expr m '[] t -> Val m t | ||
| 36 | evalExpr (ELit a) = a | ||
| 37 | evalExpr (ELam a) = a | ||
| 38 | evalExpr (EApp f a) = evalExpr $ beta a (evalExpr f) | ||
diff --git a/events/src/Events/Spec/LICENSE b/events/src/Events/Spec/LICENSE new file mode 100644 index 0000000..c28fee7 --- /dev/null +++ b/events/src/Events/Spec/LICENSE | |||
| @@ -0,0 +1,29 @@ | |||
| 1 | The code in siblings of this file is either heavily inspired by or copied from [glambda](https://hackage.haskell.org/package/glamba), an interpreter for a simply typed lambda-calculus by Richard Eisenberg under the following license: | ||
| 2 | |||
| 3 | Copyright (c) 2015, Richard Eisenberg | ||
| 4 | All rights reserved. | ||
| 5 | |||
| 6 | Redistribution and use in source and binary forms, with or without | ||
| 7 | modification, are permitted provided that the following conditions are met: | ||
| 8 | |||
| 9 | 1. Redistributions of source code must retain the above copyright notice, this | ||
| 10 | list of conditions and the following disclaimer. | ||
| 11 | |||
| 12 | 2. Redistributions in binary form must reproduce the above copyright notice, | ||
| 13 | this list of conditions and the following disclaimer in the documentation | ||
| 14 | and/or other materials provided with the distribution. | ||
| 15 | |||
| 16 | 3. Neither the name of the author nor the names of its contributors may be | ||
| 17 | used to endorse or promote products derived from this software without | ||
| 18 | specific prior written permission. | ||
| 19 | |||
| 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
| 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
| 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
| 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE | ||
| 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | ||
| 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | ||
| 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | ||
| 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
| 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file | ||
diff --git a/events/src/Events/Spec/Types.hs b/events/src/Events/Spec/Types.hs new file mode 100644 index 0000000..665958d --- /dev/null +++ b/events/src/Events/Spec/Types.hs | |||
| @@ -0,0 +1,32 @@ | |||
| 1 | {-# LANGUAGE GADTs, DataKinds, PolyKinds, TypeOperators, KindSignatures, TypeFamilies, ExplicitNamespaces #-} | ||
| 2 | |||
| 3 | module Events.Spec.Types | ||
| 4 | ( Expr(..) | ||
| 5 | , Val(..) | ||
| 6 | , Elem(..) | ||
| 7 | , Length(..) | ||
| 8 | , type (++)(..) | ||
| 9 | ) where | ||
| 10 | |||
| 11 | data Expr :: (* -> *) -> [*] -> * -> * where | ||
| 12 | ELit :: Val m a -> Expr m ctx a | ||
| 13 | EVar :: Elem a ctx -> Expr m ctx a | ||
| 14 | ELam :: Expr m (arg ': ctx) res -> Expr m ctx (arg -> res) | ||
| 15 | EApp :: Expr m ctx (arg -> a) -> Expr m ctx arg -> Expr m ctx a | ||
| 16 | |||
| 17 | type family Val m a where | ||
| 18 | Val m (a -> b) = Expr m '[a] b | ||
| 19 | Val m a = m a | ||
| 20 | |||
| 21 | data Elem :: a -> [a] -> * where | ||
| 22 | EZ :: Elem x (x ': xs) | ||
| 23 | ES :: Elem x xs -> Elem x (y ': xs) | ||
| 24 | |||
| 25 | data Length :: [a] -> * where | ||
| 26 | LZ :: Length '[] | ||
| 27 | LS :: Length xs -> Length (x ': xs) | ||
| 28 | |||
| 29 | type family (xs :: [a]) ++ (ys :: [a]) :: [a] | ||
| 30 | type instance '[] ++ ys = ys | ||
| 31 | type instance (x ': xs) ++ ys = x ': (xs ++ ys) | ||
| 32 | infixr 5 ++ | ||
diff --git a/events/src/Events/Types.hs b/events/src/Events/Types.hs index 5320bb3..6a8517b 100644 --- a/events/src/Events/Types.hs +++ b/events/src/Events/Types.hs | |||
| @@ -1,11 +1,11 @@ | |||
| 1 | {-# LANGUAGE TemplateHaskell #-} | 1 | {-# LANGUAGE TemplateHaskell, GeneralizedNewtypeDeriving #-} |
| 2 | 2 | ||
| 3 | module Events.Types | 3 | module Events.Types |
| 4 | ( TimeRange(..), rangeStart, rangeDuration | 4 | ( TimeRange(..), rangeStart, rangeDuration |
| 5 | , Event(..), payload, occursWithin | 5 | , Event(..), payload, occursWithin |
| 6 | , EvalCtx(..), ctxEvents | 6 | , EvalCtx(..), ctxEvents |
| 7 | , ObjCtx(..), objVars, objOccurs, objPayload, objCtx | 7 | , ObjCtx(..), objVars, objOccurs, objPayload, objCtx |
| 8 | , Eval | 8 | , Eval(..) |
| 9 | , module Data.Aeson | 9 | , module Data.Aeson |
| 10 | , module Data.Time.Clock | 10 | , module Data.Time.Clock |
| 11 | , module Data.Default.Class | 11 | , module Data.Default.Class |
| @@ -28,6 +28,8 @@ import Events.Types.NDT (NDT, foldNDT) | |||
| 28 | import Control.Monad.State.Lazy | 28 | import Control.Monad.State.Lazy |
| 29 | import Control.Monad.Reader | 29 | import Control.Monad.Reader |
| 30 | 30 | ||
| 31 | import Control.Applicative (Alternative(..)) | ||
| 32 | |||
| 31 | data TimeRange = TimeRange | 33 | data TimeRange = TimeRange |
| 32 | { _rangeStart :: UTCTime | 34 | { _rangeStart :: UTCTime |
| 33 | , _rangeDuration :: NominalDiffTime | 35 | , _rangeDuration :: NominalDiffTime |
| @@ -69,4 +71,16 @@ objCtx fObj ctx | |||
| 69 | | ctx ^. objOccurs = traverseOf (objPayload . _Just) fObj ctx | 71 | | ctx ^. objOccurs = traverseOf (objPayload . _Just) fObj ctx |
| 70 | | otherwise = pure ctx | 72 | | otherwise = pure ctx |
| 71 | 73 | ||
| 72 | type Eval m a = StateT ObjCtx (NDT (ReaderT EvalCtx m)) a | 74 | newtype Eval m a = Eval { unEval :: StateT ObjCtx (NDT (ReaderT EvalCtx m)) a } |
| 75 | deriving ( MonadState ObjCtx | ||
| 76 | , MonadReader EvalCtx | ||
| 77 | , MonadIO | ||
| 78 | , Functor | ||
| 79 | , Applicative | ||
| 80 | , Alternative | ||
| 81 | , Monad | ||
| 82 | , MonadPlus | ||
| 83 | ) | ||
| 84 | |||
| 85 | instance MonadTrans Eval where | ||
| 86 | lift = Eval . lift . lift . lift | ||
diff --git a/events/src/Main.hs b/events/src/Main.hs index e4b255f..410ea1d 100644 --- a/events/src/Main.hs +++ b/events/src/Main.hs | |||
| @@ -22,7 +22,7 @@ import qualified Events.Types.NDT as NDT | |||
| 22 | 22 | ||
| 23 | main :: IO () | 23 | main :: IO () |
| 24 | main = test $ do | 24 | main = test $ do |
| 25 | n <- lift $ NDT.fromFoldable ([1..] :: [Integer]) | 25 | n <- Eval . lift $ NDT.fromFoldable ([1..] :: [Integer]) |
| 26 | lower <- filter (maybe False (< fromIntegral n) <$> view (at "num" . asDouble)) <$> view ctxEvents | 26 | lower <- filter (maybe False (< fromIntegral n) <$> view (at "num" . asDouble)) <$> view ctxEvents |
| 27 | -- objOccurs .= (n <= 5) | 27 | -- objOccurs .= (n <= 5) |
| 28 | objOccurs .= (n >= 2) | 28 | objOccurs .= (n >= 2) |
