1 module Eval exposing (..)
3 import Types exposing (..)
4 import IO exposing (IO)
8 apply : Eval a -> Env -> EvalContext a
13 run : Env -> Eval a -> EvalContext a
18 withEnv : (Env -> Eval a) -> Eval a
23 setEnv : Env -> Eval ()
25 apply (succeed ()) env
28 modifyEnv : (Env -> Env) -> Eval ()
30 apply (succeed ()) (f env)
38 io : Cmd Msg -> (IO -> Eval a) -> Eval a
40 ( env, EvalIO cmd cont )
43 map : (a -> b) -> Eval a -> Eval b
46 ( env, EvalOk res ) ->
47 ( env, EvalOk (f res) )
49 ( env, EvalErr msg ) ->
52 ( env, EvalIO cmd cont ) ->
53 ( env, EvalIO cmd (cont >> map f) )
56 andThen : (a -> Eval b) -> Eval a -> Eval b
59 ( env, EvalOk res ) ->
62 ( env, EvalErr msg ) ->
65 ( env, EvalIO cmd cont ) ->
66 ( env, EvalIO cmd (cont >> andThen f) )
69 catchError : (MalExpr -> Eval a) -> Eval a -> Eval a
72 ( env, EvalOk res ) ->
75 ( env, EvalErr msg ) ->
78 ( env, EvalIO cmd cont ) ->
79 ( env, EvalIO cmd (cont >> catchError f) )
82 fail : String -> Eval a
84 ( env, EvalErr <| MalString msg )
87 throw : MalExpr -> Eval a
92 enter : Int -> List ( String, MalExpr ) -> Eval a -> Eval a
93 enter frameId bound body =
96 modifyEnv (Env.enter frameId bound)
97 |> andThen (always body)
100 modifyEnv (Env.leave env.currentFrameId)
106 {-| Apply f to expr repeatedly.
107 Continues iterating if f returns (Left eval).
108 Stops if f returns (Right expr).
113 runLoop : (MalExpr -> Env -> Either (Eval MalExpr) MalExpr) -> MalExpr -> Eval MalExpr
118 ( env, EvalOk expr ) ->
121 ( env, EvalErr msg ) ->
124 ( env, EvalIO cmd cont ) ->
125 ( env, EvalIO cmd (cont >> andThen (runLoop f)) )
131 fromResult : Result String a -> Eval a
141 {-| Chain the left and right Eval but ignore the right's result.
143 ignore : Eval b -> Eval a -> Eval a
149 |> andThen (\_ -> succeed res)