shared/names.bend

bend-lint-api@0.2.0.0 · 74 lines · 9 definitions

1import Base
2import bend-lint-api@0.2.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))