diff --git a/src/Data/Abstract/Evaluatable.hs b/src/Data/Abstract/Evaluatable.hs index d551fe7d6..533950478 100644 --- a/src/Data/Abstract/Evaluatable.hs +++ b/src/Data/Abstract/Evaluatable.hs @@ -42,6 +42,9 @@ class Evaluatable constr where default eval :: (MonadThrow Prelude.String value m, Show1 constr) => SubtermAlgebra constr term (m value) eval expr = throwException $ "Eval unspecialized for " ++ liftShowsPrec (const (const id)) (const id) 0 expr "" + +-- Instances + -- | If we can evaluate any syntax which can occur in a 'Union', we can evaluate the 'Union'. instance Apply Evaluatable fs => Evaluatable (Union fs) where eval = Prologue.apply (Proxy :: Proxy Evaluatable) eval @@ -50,6 +53,11 @@ instance Apply Evaluatable fs => Evaluatable (Union fs) where instance Evaluatable s => Evaluatable (TermF s a) where eval = eval . termFOut +--- | '[]' is treated as an imperative sequence of statements/declarations s.t.: +--- +--- 1. Each statement’s effects on the store are accumulated; +--- 2. Each statement can affect the environment of later statements (e.g. by 'modify'-ing the environment); and +--- 3. Only the last statement’s return value is returned. instance Evaluatable [] where -- 'nonEmpty' and 'foldMap1' enable us to return the last statement’s result instead of 'unit' for non-empty lists. eval = maybe unit (runApp . foldMap1 (App . subtermValue)) . nonEmpty