{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE RankNTypes #-}
module Unison.Codebase.Runtime where
import Data.Map qualified as Map
import Data.Set.NonEmpty (NESet)
import Unison.ABT qualified as ABT
import Unison.Builtin.Decls (tupleTerm, pattern TupleTerm')
import Unison.Codebase.CodeLookup qualified as CL
import Unison.Codebase.CodeLookup.Util qualified as CL
import Unison.Hashing.V2.Convert qualified as Hashing
import Unison.Parser.Ann (Ann)
import Unison.Prelude
import Unison.PrettyPrintEnv qualified as PPE
import Unison.Reference (Reference)
import Unison.Reference qualified as Reference
import Unison.Term qualified as Term
import Unison.Type (Type)
import Unison.UnisonFile (TypecheckedUnisonFile)
import Unison.UnisonFile qualified as UF
import Unison.Util.Pretty qualified as P
import Unison.Var (Var)
import Unison.Var qualified as Var
import Unison.WatchKind (WatchKind)
import Unison.WatchKind qualified as WK
type Error = P.Pretty P.ColorText
type Term v = Term.Term v ()
data CompileOpts = COpts
{ CompileOpts -> Bool
profile :: Bool
}
defaultCompileOpts :: CompileOpts
defaultCompileOpts :: CompileOpts
defaultCompileOpts = COpts {$sel:profile:COpts :: Bool
profile = Bool
False}
data Runtime v = Runtime
{ forall v. Runtime v -> IO ()
terminate :: IO (),
forall v.
Runtime v
-> CodeLookup v IO ()
-> PrettyPrintEnv
-> Term v
-> IO (Either Error ([Error], Term v))
evaluate ::
CL.CodeLookup v IO () ->
PPE.PrettyPrintEnv ->
Term v ->
IO (Either Error ([Error], Term v)),
forall v.
Runtime v
-> CompileOpts
-> CodeLookup v IO ()
-> PrettyPrintEnv
-> Reference
-> FilePath
-> IO (Maybe Error)
compileTo ::
CompileOpts ->
CL.CodeLookup v IO () ->
PPE.PrettyPrintEnv ->
Reference ->
FilePath ->
IO (Maybe Error),
forall v. Runtime v -> Type v Ann
mainType :: Type v Ann,
forall v. Runtime v -> NESet (Type v Ann)
ioTestTypes :: NESet (Type v Ann)
}
type IsCacheHit = Bool
noCache :: Reference.Id -> IO (Maybe (Term v))
noCache :: forall v. Id -> IO (Maybe (Term v))
noCache Id
_ = Maybe (Term v) -> IO (Maybe (Term v))
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe (Term v)
forall a. Maybe a
Nothing
type WatchResults v a =
( Either
Error
( [(v, Term v)],
[Error],
Map v (a, WatchKind, Reference.Id, Term v, Term v, IsCacheHit)
)
)
evaluateWatches ::
forall v a.
(Var v) =>
CL.CodeLookup v IO a ->
PPE.PrettyPrintEnv ->
(Reference.Id -> IO (Maybe (Term v))) ->
Runtime v ->
TypecheckedUnisonFile v a ->
IO (WatchResults v a)
evaluateWatches :: forall v a.
Var v =>
CodeLookup v IO a
-> PrettyPrintEnv
-> (Id -> IO (Maybe (Term v)))
-> Runtime v
-> TypecheckedUnisonFile v a
-> IO (WatchResults v a)
evaluateWatches CodeLookup v IO a
code PrettyPrintEnv
ppe Id -> IO (Maybe (Term2 v () () v ()))
evaluationCache Runtime v
rt TypecheckedUnisonFile v a
tuf = do
let m :: Map v (Reference.Id, Term.Term v a)
m :: Map v (Id, Term v a)
m = ((a, Id, Maybe FilePath, Term v a, Type v a) -> (Id, Term v a))
-> Map v (a, Id, Maybe FilePath, Term v a, Type v a)
-> Map v (Id, Term v a)
forall a b. (a -> b) -> Map v a -> Map v b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\(a
_a, Id
id, Maybe FilePath
_wk, Term v a
tm, Type v a
_tp) -> (Id
id, Term v a
tm)) (TypecheckedUnisonFile v a
-> Map v (a, Id, Maybe FilePath, Term v a, Type v a)
forall v a.
TypecheckedUnisonFile v a
-> Map v (a, Id, Maybe FilePath, Term v a, Type v a)
UF.hashTermsId TypecheckedUnisonFile v a
tuf)
Set v
watches :: Set v = Map v FilePath -> Set v
forall k a. Map k a -> Set k
Map.keysSet Map v FilePath
watchKinds
watchKinds :: Map v WatchKind
watchKinds :: Map v FilePath
watchKinds =
[(v, FilePath)] -> Map v FilePath
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList
[(v
v, FilePath
k) | (FilePath
k, [(v, a, Term v a, Type v a)]
ws) <- TypecheckedUnisonFile v a
-> [(FilePath, [(v, a, Term v a, Type v a)])]
forall v a.
TypecheckedUnisonFile v a
-> [(FilePath, [(v, a, Term v a, Type v a)])]
UF.watchComponents TypecheckedUnisonFile v a
tuf, (v
v, a
_a, Term v a
_tm, Type v a
_tp) <- [(v, a, Term v a, Type v a)]
ws]
unann :: Term v a -> Term2 v () () v ()
unann = (a -> ()) -> Term v a -> Term2 v () () v ()
forall v a a2. Ord v => (a -> a2) -> Term v a -> Term v a2
Term.amap (() -> a -> ()
forall a b. a -> b -> a
const ())
Map v (Id, a, Term2 v () () v (), Bool)
m' <- ([(v, (Id, a, Term2 v () () v (), Bool))]
-> Map v (Id, a, Term2 v () () v (), Bool))
-> IO [(v, (Id, a, Term2 v () () v (), Bool))]
-> IO (Map v (Id, a, Term2 v () () v (), Bool))
forall a b. (a -> b) -> IO a -> IO b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [(v, (Id, a, Term2 v () () v (), Bool))]
-> Map v (Id, a, Term2 v () () v (), Bool)
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList (IO [(v, (Id, a, Term2 v () () v (), Bool))]
-> IO (Map v (Id, a, Term2 v () () v (), Bool)))
-> (((v, (Id, Term v a))
-> IO (v, (Id, a, Term2 v () () v (), Bool)))
-> IO [(v, (Id, a, Term2 v () () v (), Bool))])
-> ((v, (Id, Term v a))
-> IO (v, (Id, a, Term2 v () () v (), Bool)))
-> IO (Map v (Id, a, Term2 v () () v (), Bool))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(v, (Id, Term v a))]
-> ((v, (Id, Term v a))
-> IO (v, (Id, a, Term2 v () () v (), Bool)))
-> IO [(v, (Id, a, Term2 v () () v (), Bool))]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
t a -> (a -> f b) -> f (t b)
for (Map v (Id, Term v a) -> [(v, (Id, Term v a))]
forall k a. Map k a -> [(k, a)]
Map.toList Map v (Id, Term v a)
m) (((v, (Id, Term v a)) -> IO (v, (Id, a, Term2 v () () v (), Bool)))
-> IO (Map v (Id, a, Term2 v () () v (), Bool)))
-> ((v, (Id, Term v a))
-> IO (v, (Id, a, Term2 v () () v (), Bool)))
-> IO (Map v (Id, a, Term2 v () () v (), Bool))
forall a b. (a -> b) -> a -> b
$ \(v
v, (Id
r, Term v a
t)) -> do
Maybe (Term2 v () () v ())
o <- Id -> IO (Maybe (Term2 v () () v ()))
evaluationCache Id
r
case Maybe (Term2 v () () v ())
o of
Maybe (Term2 v () () v ())
Nothing -> (v, (Id, a, Term2 v () () v (), Bool))
-> IO (v, (Id, a, Term2 v () () v (), Bool))
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (v
v, (Id
r, Term v a -> a
forall (f :: * -> *) v a. Term f v a -> a
ABT.annotation Term v a
t, Term v a -> Term2 v () () v ()
forall {a}. Term v a -> Term2 v () () v ()
unann Term v a
t, Bool
False))
Just Term2 v () () v ()
t' -> (v, (Id, a, Term2 v () () v (), Bool))
-> IO (v, (Id, a, Term2 v () () v (), Bool))
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (v
v, (Id
r, Term v a -> a
forall (f :: * -> *) v a. Term f v a -> a
ABT.annotation Term v a
t, Term2 v () () v ()
t', Bool
True))
let rv :: Map Reference.Id v
rv :: Map Id v
rv = [(Id, v)] -> Map Id v
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList [(Id
r, v
v) | (v
v, (Id
r, Term v a
_)) <- Map v (Id, Term v a) -> [(v, (Id, Term v a))]
forall k a. Map k a -> [(k, a)]
Map.toList Map v (Id, Term v a)
m]
bindings :: [(v, (), Term v)]
bindings :: [(v, (), Term2 v () () v ())]
bindings = [(v
v, (), Map Id v -> Term2 v () () v () -> Term2 v () () v ()
forall {v} {typeVar} {typeAnn} {patternAnn} {a}.
Ord v =>
Map Id v
-> Term (F typeVar typeAnn patternAnn) v a
-> Term (F typeVar typeAnn patternAnn) v a
unref Map Id v
rv Term2 v () () v ()
b) | (v
v, (Id
_, a
_, Term2 v () () v ()
b, Bool
_)) <- Map v (Id, a, Term2 v () () v (), Bool)
-> [(v, (Id, a, Term2 v () () v (), Bool))]
forall k a. Map k a -> [(k, a)]
Map.toList Map v (Id, a, Term2 v () () v (), Bool)
m']
watchVars :: [Term2 v () () v ()]
watchVars = [() -> v -> Term2 v () () v ()
forall a v vt at ap. a -> v -> Term2 vt at ap v a
Term.var () v
v | v
v <- Set v -> [v]
forall a. Set a -> [a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList Set v
watches]
bigOl'LetRec :: Term2 v () () v ()
bigOl'LetRec = Bool
-> [(v, (), Term2 v () () v ())]
-> Term2 v () () v ()
-> Term2 v () () v ()
forall v a vt.
(Ord v, Monoid a) =>
Bool -> [(v, a, Term' vt v a)] -> Term' vt v a -> Term' vt v a
Term.letRec' Bool
True [(v, (), Term2 v () () v ())]
bindings ([Term2 v () () v ()] -> Term2 v () () v ()
forall v a vt at ap.
(Var v, Monoid a) =>
[Term2 vt at ap v a] -> Term2 vt at ap v a
tupleTerm [Term2 v () () v ()]
watchVars)
cl :: CodeLookup v IO ()
cl = CodeLookup v IO a -> CodeLookup v IO ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (TypecheckedUnisonFile v a -> CodeLookup v IO a
forall (m :: * -> *) v a.
(Var v, Monad m) =>
TypecheckedUnisonFile v a -> CodeLookup v m a
CL.fromTypecheckedUnisonFile TypecheckedUnisonFile v a
tuf) CodeLookup v IO () -> CodeLookup v IO () -> CodeLookup v IO ()
forall a. Semigroup a => a -> a -> a
<> CodeLookup v IO a -> CodeLookup v IO ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void CodeLookup v IO a
code
Either Error ([Error], Term2 v () () v ())
out <- Runtime v
-> CodeLookup v IO ()
-> PrettyPrintEnv
-> Term2 v () () v ()
-> IO (Either Error ([Error], Term2 v () () v ()))
forall v.
Runtime v
-> CodeLookup v IO ()
-> PrettyPrintEnv
-> Term v
-> IO (Either Error ([Error], Term v))
evaluate Runtime v
rt CodeLookup v IO ()
cl PrettyPrintEnv
ppe Term2 v () () v ()
bigOl'LetRec
case Either Error ([Error], Term2 v () () v ())
out of
Right ([Error]
errs, Term2 v () () v ()
out) -> do
let ([(v, Term2 v () () v ())]
bindings, [Term2 v () () v ()]
results) = case Term2 v () () v ()
out of
TupleTerm' [Term2 v () () v ()]
results -> ([(v, Term2 v () () v ())]
forall a. Monoid a => a
mempty, [Term2 v () () v ()]
results)
Term.LetRecNamed' [(v, Term2 v () () v ())]
bs (TupleTerm' [Term2 v () () v ()]
results) -> ([(v, Term2 v () () v ())]
bs, [Term2 v () () v ()]
results)
Term2 v () () v ()
_ -> FilePath -> ([(v, Term2 v () () v ())], [Term2 v () () v ()])
forall a. HasCallStack => FilePath -> a
error (FilePath -> ([(v, Term2 v () () v ())], [Term2 v () () v ()]))
-> FilePath -> ([(v, Term2 v () () v ())], [Term2 v () () v ()])
forall a b. (a -> b) -> a -> b
$ FilePath
"Evaluation should produce a tuple, but gave: " FilePath -> FilePath -> FilePath
forall a. [a] -> [a] -> [a]
++ Term2 v () () v () -> FilePath
forall a. Show a => a -> FilePath
show Term2 v () () v ()
out
let go :: v
-> Term2 v () () v ()
-> (Id, a, Term2 v () () v (), Bool)
-> (a, FilePath, Id, Term2 v () () v (), Term2 v () () v (), Bool)
go v
v Term2 v () () v ()
eval (Id
ref, a
a, Term2 v () () v ()
uneval, Bool
isHit) =
( a
a,
FilePath -> v -> Map v FilePath -> FilePath
forall k a. Ord k => a -> k -> Map k a -> a
Map.findWithDefault (v -> FilePath
forall {a} {a}. Show a => a -> a
die v
v) v
v Map v FilePath
watchKinds,
Id
ref,
Term2 v () () v ()
uneval,
Term2 v () () v () -> Term2 v () () v ()
forall v. Ord v => Term0 v -> Term0 v
Term.etaNormalForm Term2 v () () v ()
eval,
Bool
isHit
)
watchMap :: Map
v (a, FilePath, Id, Term2 v () () v (), Term2 v () () v (), Bool)
watchMap =
(v
-> Term2 v () () v ()
-> (Id, a, Term2 v () () v (), Bool)
-> (a, FilePath, Id, Term2 v () () v (), Term2 v () () v (), Bool))
-> Map v (Term2 v () () v ())
-> Map v (Id, a, Term2 v () () v (), Bool)
-> Map
v (a, FilePath, Id, Term2 v () () v (), Term2 v () () v (), Bool)
forall k a b c.
Ord k =>
(k -> a -> b -> c) -> Map k a -> Map k b -> Map k c
Map.intersectionWithKey
v
-> Term2 v () () v ()
-> (Id, a, Term2 v () () v (), Bool)
-> (a, FilePath, Id, Term2 v () () v (), Term2 v () () v (), Bool)
go
([(v, Term2 v () () v ())] -> Map v (Term2 v () () v ())
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList (Set v -> [v]
forall a. Set a -> [a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList Set v
watches [v] -> [Term2 v () () v ()] -> [(v, Term2 v () () v ())]
forall a b. [a] -> [b] -> [(a, b)]
`zip` [Term2 v () () v ()]
results))
Map v (Id, a, Term2 v () () v (), Bool)
m'
die :: a -> a
die a
v = FilePath -> a
forall a. HasCallStack => FilePath -> a
error (FilePath -> a) -> FilePath -> a
forall a b. (a -> b) -> a -> b
$ FilePath
"not sure what kind of watch this is: " FilePath -> FilePath -> FilePath
forall a. Semigroup a => a -> a -> a
<> a -> FilePath
forall a. Show a => a -> FilePath
show a
v
WatchResults v a -> IO (WatchResults v a)
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (WatchResults v a -> IO (WatchResults v a))
-> WatchResults v a -> IO (WatchResults v a)
forall a b. (a -> b) -> a -> b
$ ([(v, Term2 v () () v ())], [Error],
Map
v (a, FilePath, Id, Term2 v () () v (), Term2 v () () v (), Bool))
-> WatchResults v a
forall a b. b -> Either a b
Right ([(v, Term2 v () () v ())]
bindings, [Error]
errs, Map
v (a, FilePath, Id, Term2 v () () v (), Term2 v () () v (), Bool)
watchMap)
Left Error
e -> WatchResults v a -> IO (WatchResults v a)
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Error -> WatchResults v a
forall a b. a -> Either a b
Left Error
e)
where
unref :: Map Id v
-> Term (F typeVar typeAnn patternAnn) v a
-> Term (F typeVar typeAnn patternAnn) v a
unref Map Id v
rv Term (F typeVar typeAnn patternAnn) v a
t = (Term (F typeVar typeAnn patternAnn) v a
-> Maybe (Term (F typeVar typeAnn patternAnn) v a))
-> Term (F typeVar typeAnn patternAnn) v a
-> Term (F typeVar typeAnn patternAnn) v a
forall (f :: * -> *) v a.
(Traversable f, Ord v) =>
(Term f v a -> Maybe (Term f v a)) -> Term f v a -> Term f v a
ABT.visitPure Term (F typeVar typeAnn patternAnn) v a
-> Maybe (Term (F typeVar typeAnn patternAnn) v a)
go Term (F typeVar typeAnn patternAnn) v a
t
where
go :: Term (F typeVar typeAnn patternAnn) v a
-> Maybe (Term (F typeVar typeAnn patternAnn) v a)
go t :: Term (F typeVar typeAnn patternAnn) v a
t@(Term.Ref' (Reference.DerivedId Id
r)) = case Id -> Map Id v -> Maybe v
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup Id
r Map Id v
rv of
Maybe v
Nothing -> Maybe (Term (F typeVar typeAnn patternAnn) v a)
forall a. Maybe a
Nothing
Just v
v -> Term (F typeVar typeAnn patternAnn) v a
-> Maybe (Term (F typeVar typeAnn patternAnn) v a)
forall a. a -> Maybe a
Just (a -> v -> Term (F typeVar typeAnn patternAnn) v a
forall a v vt at ap. a -> v -> Term2 vt at ap v a
Term.var (Term (F typeVar typeAnn patternAnn) v a -> a
forall (f :: * -> *) v a. Term f v a -> a
ABT.annotation Term (F typeVar typeAnn patternAnn) v a
t) v
v)
go Term (F typeVar typeAnn patternAnn) v a
_ = Maybe (Term (F typeVar typeAnn patternAnn) v a)
forall a. Maybe a
Nothing
evaluateTerm' ::
(Var v, Monoid a) =>
CL.CodeLookup v IO a ->
(Reference.Id -> IO (Maybe (Term v))) ->
PPE.PrettyPrintEnv ->
Runtime v ->
Term.Term v a ->
IO (Either Error ([Error], Term v))
evaluateTerm' :: forall v a.
(Var v, Monoid a) =>
CodeLookup v IO a
-> (Id -> IO (Maybe (Term v)))
-> PrettyPrintEnv
-> Runtime v
-> Term v a
-> IO (Either Error ([Error], Term v))
evaluateTerm' CodeLookup v IO a
codeLookup Id -> IO (Maybe (Term v))
cache PrettyPrintEnv
ppe Runtime v
rt Term v a
tm = do
Maybe (Term v)
result <- Id -> IO (Maybe (Term v))
cache (Term v a -> Id
forall v a. Var v => Term v a -> Id
Hashing.hashClosedTerm Term v a
tm)
case Maybe (Term v)
result of
Just Term v
r -> Either Error ([Error], Term v)
-> IO (Either Error ([Error], Term v))
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (([Error], Term v) -> Either Error ([Error], Term v)
forall a b. b -> Either a b
Right ([], Term v
r))
Maybe (Term v)
Nothing -> do
let tuf :: TypecheckedUnisonFile v a
tuf =
Map v (Id, DataDeclaration v a)
-> Map v (Id, EffectDeclaration v a)
-> [[(v, a, Term v a, Type v a)]]
-> [(FilePath, [(v, a, Term v a, Type v a)])]
-> TypecheckedUnisonFile v a
forall v a.
Var v =>
Map v (Id, DataDeclaration v a)
-> Map v (Id, EffectDeclaration v a)
-> [[(v, a, Term v a, Type v a)]]
-> [(FilePath, [(v, a, Term v a, Type v a)])]
-> TypecheckedUnisonFile v a
UF.typecheckedUnisonFile
Map v (Id, DataDeclaration v a)
forall a. Monoid a => a
mempty
Map v (Id, EffectDeclaration v a)
forall a. Monoid a => a
mempty
[[(v, a, Term v a, Type v a)]]
forall a. Monoid a => a
mempty
[(FilePath
forall a. (Eq a, IsString a) => a
WK.RegularWatch, [(FilePath -> v
forall v. Var v => FilePath -> v
Var.nameds FilePath
"result", a
forall a. Monoid a => a
mempty, Term v a
tm, Ann -> a
forall a. Monoid a => a
mempty (Ann -> a) -> Term F v Ann -> Type v a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Runtime v -> Term F v Ann
forall v. Runtime v -> Type v Ann
mainType Runtime v
rt)])]
WatchResults v ()
r <- CodeLookup v IO ()
-> PrettyPrintEnv
-> (Id -> IO (Maybe (Term v)))
-> Runtime v
-> TypecheckedUnisonFile v ()
-> IO (WatchResults v ())
forall v a.
Var v =>
CodeLookup v IO a
-> PrettyPrintEnv
-> (Id -> IO (Maybe (Term v)))
-> Runtime v
-> TypecheckedUnisonFile v a
-> IO (WatchResults v a)
evaluateWatches (CodeLookup v IO a -> CodeLookup v IO ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void CodeLookup v IO a
codeLookup) PrettyPrintEnv
ppe Id -> IO (Maybe (Term v))
cache Runtime v
rt (TypecheckedUnisonFile v a -> TypecheckedUnisonFile v ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void TypecheckedUnisonFile v a
tuf)
pure $
WatchResults v ()
r WatchResults v ()
-> (([(v, Term v)], [Error],
Map v ((), FilePath, Id, Term v, Term v, Bool))
-> ([Error], Term v))
-> Either Error ([Error], Term v)
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> \([(v, Term v)]
_, [Error]
errs, Map v ((), FilePath, Id, Term v, Term v, Bool)
map) ->
case Map v ((), FilePath, Id, Term v, Term v, Bool)
-> [((), FilePath, Id, Term v, Term v, Bool)]
forall k a. Map k a -> [a]
Map.elems Map v ((), FilePath, Id, Term v, Term v, Bool)
map of
[(()
_loc, FilePath
_kind, Id
_hash, Term v
_src, Term v
value, Bool
_isHit)] -> ([Error]
errs, Term v
value)
[((), FilePath, Id, Term v, Term v, Bool)]
_ -> FilePath -> ([Error], Term v)
forall a. HasCallStack => FilePath -> a
error FilePath
"evaluateTerm': Pattern mismatch on watch results"
evaluateTerm ::
(Var v, Monoid a) =>
CL.CodeLookup v IO a ->
PPE.PrettyPrintEnv ->
Runtime v ->
Term.Term v a ->
IO (Either Error ([Error], Term v))
evaluateTerm :: forall v a.
(Var v, Monoid a) =>
CodeLookup v IO a
-> PrettyPrintEnv
-> Runtime v
-> Term v a
-> IO (Either Error ([Error], Term v))
evaluateTerm CodeLookup v IO a
codeLookup = CodeLookup v IO a
-> (Id -> IO (Maybe (Term v)))
-> PrettyPrintEnv
-> Runtime v
-> Term v a
-> IO (Either Error ([Error], Term v))
forall v a.
(Var v, Monoid a) =>
CodeLookup v IO a
-> (Id -> IO (Maybe (Term v)))
-> PrettyPrintEnv
-> Runtime v
-> Term v a
-> IO (Either Error ([Error], Term v))
evaluateTerm' CodeLookup v IO a
codeLookup Id -> IO (Maybe (Term v))
forall v. Id -> IO (Maybe (Term v))
noCache