Std.Access
View source →Access protocol and composable lenses, modelled on Elixir's
Access behaviour.
The module has four layers:
- A
proto Access(C)protocol withfetch/2,get_and_update/3, andpop/2callbacks. Implementations are provided for plain maps (which also covers records, since Cure records compile to BEAM maps with a__struct__discriminator) and for keyword-style lists of%[key, value]pairs. - Direct helpers (
fetch/2,fetch_bang/2,get/3,get_and_update/3,pop/2) that wrap the protocol callbacks. - An
AccessorADT with factory functions (key,key_default,key_bang,elem_at,at,all,filter) that serve as composable lenses, analogous to Elixir'sAccess.key/2,Access.at/1,Access.all/0, andAccess.filter/1. - Nested traversal helpers (
fetch_in/2,get_in/2,put_in/3,update_in/3,get_and_update_in/3,pop_in/2) that accept a list ofAccessorvalues and walk nested data structures.
Examples
use Std.Access
let m = Std.Map.from_list([%[:user, Std.Map.from_list([%[:name, "Ada"]])]])
get_in(m, [key(:user), key(:name)]) # => "Ada"
put_in(m, [key(:user), key(:name)], "Grace")
use Std.Access
# Bump every score in a list of users.
let users = [
Std.Map.from_list([%[:name, "Ada"], %[:score, 10]]),
Std.Map.from_list([%[:name, "Grace"], %[:score, 20]])
]
update_in(users, [all(), key(:score)], fn(s) -> s + 1)
Types
-
type Accessor = AccKey | AccKeyDefault | AccKeyReq | AccTupleElem | AccListAt | AccListAll | AccListFilterTagged union of composable lenses consumed by the nested-traversal helpers (
fetch_in,get_in,put_in, ...).
Protocols
-
proto Access(C)Key-addressable container protocol:
fetch,get_and_update,pop.
Functions
-
# fn __group__() -> Atom
Group tag consumed by
Cure.Stdlib.Preload. -
# fn all() -> Accessor
Traverse every element of a list.
-
# fn at(i: Int) -> Accessor
0-based list index accessor.
-
# fn elem_at(i: Int) -> Accessor
0-based tuple element accessor (translated to 1-based for the BEAM).
-
# fn fetch(container: Map(Any, Any), key: Any) -> Option(Any)
Wrap
Std.Map.get/2in anOption. -
# fn fetch(container: List(Any), key: Any) -> Option(Any)
Find
keyin a keyword-style list. -
# fn fetch_bang(container: C, key: Any) -> Any
Like
fetch/2, but raises:key_errorif the key is missing. -
# fn fetch_in(container: Any, keys: List(Accessor)) -> Option(Any)
Walk
keysthroughcontainer; returnsSome(leaf)orNone()if any intermediate lookup is missing. -
# fn filter(pred: (Any) -> Bool) -> Accessor
Traverse every element of a list that satisfies
pred. -
# fn get(container: C, key: Any, default: Any) -> Any
Fetch the value under
key, falling back todefaultwhen absent. -
# fn get_and_update(container: Map(Any, Any), key: Any, f: (Any) -> Any) -> Tuple
Protocol
get_and_updatefor maps; honours the:popsentinel. -
# fn get_and_update(container: List(Any), key: Any, f: (Any) -> Any) -> Tuple
Protocol
get_and_updatefor keyword lists. -
# fn get_and_update_in(container: Any, keys: List(Accessor), f: (Any) -> Any) -> Tuple
The full get-and-update workhorse:
freceives the leaf and must return%[got, new_leaf]or the atom:pop. Returns%[got, rebuilt_container]. -
# fn get_in(container: Any, keys: List(Accessor)) -> Any
Walk
keysthroughcontainer; returnsnilfor missing paths. -
# fn key(k: Any) -> Accessor
Plain key accessor. Missing keys collapse to
nilinget_in. -
# fn key_bang(k: Any) -> Accessor
Required key accessor. Missing keys raise
:key_error. -
# fn key_default(k: Any, default: Any) -> Accessor
Key accessor with a default substituted when the key is missing.
-
# fn pop(container: Map(Any, Any), key: Any) -> Tuple
Protocol
popfor maps. Raises on records (struct maps). -
# fn pop(container: List(Any), key: Any) -> Tuple
Protocol
popfor keyword lists. -
# fn pop_in(container: Any, keys: List(Accessor)) -> Tuple
Remove the leaf reached by
keys, returning%[popped, rebuilt]. -
# fn put_in(container: Any, keys: List(Accessor), value: Any) -> Any
Replace the leaf reached by
keyswithvalue, rebuilding intermediate containers along the way. -
# fn update_in(container: Any, keys: List(Accessor), f: (Any) -> Any) -> Any
Apply
fto the leaf reached bykeys, rebuilding intermediate containers along the way.