Skip to content

Instantly share code, notes, and snippets.

@brosenan
Created November 9, 2019 07:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save brosenan/f2d0d4f7f820c95f6152c1ca3e18fe3b to your computer and use it in GitHub Desktop.
Save brosenan/f2d0d4f7f820c95f6152c1ca3e18fe3b to your computer and use it in GitHub Desktop.
type result(T, E) = ok(T) | err(E).
decl E is error, T1 is any, T2 is any, F is T1 -> result(T2, E) =>
check(result(T1, E), F) -> result(T2, E).
check(R, F) := case R of {
ok(V) => F!V,
err(E) => err(E)
}.
class S is scenario where {
done(&S) -> bool,
T is any, Err is error, IO is io(T, Err) + eq =>
match(&S, IO) -> result(T, simulation_err),
Next is scenario =>
next(S) -> Next
}.
Ret is any, Err is error =>
class P is proc(Ret, Err) where {
run(P) -> result(Ret, Err),
S is scenario =>
simulate(P, S) -> result(Ret, simulation_err)
}.
type return(Ret).
Ret is any, Err is error =>
instance return(Ret) is proc(Ret, Err) where {
run(return(Ret)) := ok(Ret),
simulate(return(Ret), S) := case done(S) of {
true => ok(Ret),
false => err(premature_end_of_simulation)
}
}.
Ret is any, Err is error =>
class IO is io(Ret, Err) where {
exec(IO) -> result(Ret, Err)
}.
type do(result(T, Err), F).
Ret is any, Err is error, Next is proc(Ret, Err),
T is any, F is (T -> Next), IO is io(T, Err) =>
instance do(IO, F) is proc(Ret, Err) where {
run(do(IO, F)) := case exec(IO) of {
ok(V) => run(F!V),
err(Err) => err(Err)
}
simulate(do(IO, F), S) := case match(&S, IO) of {
ok(V) => simulate(F!V, next(S)),
err(Err) => err(Err)
}
}.
type end.
instance end is scenario where {
done(end) := true,
match(end, _) := err(premature_end_of_scenario),
next(end) := end
}
type and_then(IO, T, Next).
T is any, Err is error, IO is io(T, Err), Next is scenario =>
instance and_then(IO, T, Next) is scenario where {
done(and_then(_, _, _)) := false,
match(and_then(IO, V, _), IO1) := case IO == IO1 of {
true: ok(V),
false: err(action_mismatch(IO, IO1))
}
next(and_then(_, _, Next)) := Next
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment