src/lazy/lazy.bend

bolt@1.11.0.0 · 41 lines · 0 definitions

1# lazy: branches that do not run both ways. Bool.pick, Bool.and and Bool.or
2# are ordinary defs, so every argument is evaluated before the call: a
3# search written as `Bool.pick(T, hit, here, go(rest))` walks the whole list
4# whatever `hit` says (measured native, 100 iterations over 100k cells: the
5# hit at the head costs 0.10 s, the same as the hit at the end, while the
6# forms here cost 0.00 s). A thunk `Unit -> T` is a value, so the branch
7# that is not taken is never applied.
8import Base
9
10# `a` when c, else what rest gives: the early exit of a search
11def stop(-A: Type, cc: Bool, aa: A, rest: Unit -> A) -> A:
12  match cc:
13    case True{}:
14      aa
15    case False{}:
16      rest(Unit{})
17
18# True when a, else what rest gives: `or` that stops at the first True
19def or_else(aa: Bool, rest: Unit -> Bool) -> Bool:
20  match aa:
21    case True{}:
22      True{}
23    case False{}:
24      rest(Unit{})
25
26# what rest gives when a, else False: `and` that stops at the first False
27def and_then(aa: Bool, rest: Unit -> Bool) -> Bool:
28  match aa:
29    case True{}:
30      rest(Unit{})
31    case False{}:
32      False{}
33
34# what yes gives when c, else what no gives: a pick whose two branches each
35# recurse, only the one taken run
36def either(-A: Type, cc: Bool, yes: Unit -> A, no: Unit -> A) -> A:
37  match cc:
38    case True{}:
39      yes(Unit{})
40    case False{}:
41      no(Unit{})