shared/names.bend
bend-lint-api@0.1.0.0 · 74 lines · 0 definitions
1import Base
2import bend-lint-api@0.1.0.0/shared/lists.bend as Lists
3
4# A value, with the name it is written as.
5type Named<-A: Data> is Data:
6 Named{name: String, value: A}
7
8def lookup.go(
9 -A: Data,
10 +key: String,
11 table: List<&2, Named<A>>,
12 found: Maybe<&2, A>
13) -> Maybe<&2, A>:
14 match table found:
15 case _ Some{v}:
16 Some{v}
17 case Nil{} None{}:
18 None{}
19 case Con{Named{k, v}, rest} None{}:
20 lookup.go(A, key, rest, Lists.when(A, String.eq(k, key), v))
21
22# Each of `xs` with the name `show` gives it: a table for `lookup`, so that each name is written once, in `show`.
23def table(~A: Data, ~show: A -> String, xs: List<&2, A>) -> List<&2, Named<A>>:
24 match xs:
25 case Nil{}:
26 []
27 case Con{+x, rest}:
28 Named{show(x), x} <> table(~A, ~show, rest)
29
30# The value `key` names in `table`: the first, read no further.
31def lookup(-A: Data, key: String, table: List<&2, Named<A>>) -> Maybe<&2, A>:
32 lookup.go(A, key, table, None{})
33
34# The value `key` names in `table`, a map by name (as `Lint.definitions` makes): one pass over the name, however many
35# names there are.
36def find(-A: Data, table: Map<&2, Maybe<&2, A>>, key: String) -> Maybe<&2, A>:
37 Pair.snd(Map<&2, Maybe<&2, A>>, Maybe<&2, A>, Map.get(Maybe<&2, A>, None{}, table, key))
38
39# Groups
40# ======
41# Values by name, in a map: each name's values, last first.
42def Group.add.of(
43 -A: Data,
44 got: Map<&2, List<&2, A>> & List<&2, A>,
45 key: String,
46 x: A
47) -> Map<&2, List<&2, A>>:
48 match got:
49 case Tuple{groups, old}:
50 Map.set(&2, List<&2, A>, groups, key, x <> old)
51
52# `groups` with `x` added under `key`. A key's list is last first; `Group.get` gives it in order.
53def Group.add(-A: Data, groups: Map<&2, List<&2, A>>, +key: String, x: A) -> Map<&2, List<&2, A>>:
54 Group.add.of(A, Map.get(List<&2, A>, [], groups, key), key, x)
55
56# What is added under `key`, in the order added.
57def Group.get(-A: Data, groups: Map<&2, List<&2, A>>, key: String) -> List<&2, A>:
58 List.reverse(
59 &2,
60 A,
61 Pair.snd(Map<&2, List<&2, A>>, List<&2, A>, Map.get(List<&2, A>, [], groups, key))
62 )
63
64def Group.of(
65 ~A: Data,
66 ~key: A -> String,
67 xs: List<&2, A>,
68 groups: Map<&2, List<&2, A>>
69) -> Map<&2, List<&2, A>>:
70 match xs:
71 case Nil{}:
72 groups
73 case Con{+x, rest}:
74 Group.of(~A, ~key, rest, Group.add(A, groups, key(x), x))