++mop
Ordered map mold builder
Constructs and validates an ordered map based on key type, value type and a comparator gate.
Ordinary maps are always ordered by the ++mug hash of their keys, while mops are ordered by a comparator gate of your choosing.
Accepts
++mop has two layers, the first is a wet gate that takes two molds:
- keyis a- mold, the type of the map key.
- valueis a- mold, the type of the map value.
The wet gate produces a dry gate that takes:
- ordis a binary comparator- gateof- $-([key key] ?)used to determine item ordering. It produces- .yif the first key should be first, and- .nif it should be second.
Warning:
Ordered maps will not work properly if two keys can be unequal under noun equality but equal via the compare gate.
Produces
A mold.
Source
++ mop|* [key=mold value=mold]|= ord=$-([key key] ?)|= a=*=/ b ;;((tree [key=key val=value]) a)?> (apt:((on key value) ord) b)b
Examples
> *((mop @ @) gth){}
Descending order:
> (gas:((on @ @) gth) *((mop @ @) gth) 1^1 2^2 3^3 ~){[key=3 val=3] [key=2 val=2] [key=1 val=1]}
Ascending order:
> (gas:((on @ @) lth) *((mop @ @) lth) 1^1 2^2 3^3 ~){[key=1 val=1] [key=2 val=2] [key=3 val=3]}
Molding a correctly ordered mop
> =a (gas:((on @ @) gth) *((mop @ @) gth) 1^1 2^2 3^3 ~)> (((mop @ @) gth) a){[key=3 val=3] [key=2 val=2] [key=1 val=1]}
Molding an incorrectly ordered mop:
> =a (malt 1^1 2^2 3^3 4^4 5^5 ~)> (((mop @ @) gth) a)dojo: hoon expression failed
Note you can't use ordinary map constructors like ++malt to make a mop as it'll be in the wrong order.
++ordered-map
A synonym for ++on.
Source
++ ordered-map on
++on
Ordered map operations
Container arm for mop operation arms. A mop is an ordered set of key-value pairs.
Accepts
++on has two layers, the first is a wet gate that takes two molds:
- keyis a- mold, the type of the map keys.
- valis a- mold, the type of the map values.
The wet gate produces a dry gate that takes:
- compareis a binary comparator- gateof- $-([key key] ?)used to determine item ordering. It produces- .yif the first key should be first, and- .nif it should be second.
Produces
A core whose arms perform the various mop operations.
Source
++ on~/ %on|* [key=mold val=mold]=> |%+$ item [key=key val=val]--~% %comp +>+ ~|= compare=$-([key key] ?)~% %core + ~|%
Examples
> *((on @ @) gth)< 20.htd1.ogd[ compare=<1|xpg [[@ @] [@ @] ?(%.y %.n)]>< 1.twi1.wlm[ [ key=<1.vde [* [our=@p now=@da eny=@uvJ] <17.ayh 34.ygp 14.usy 54.fbg 77.kga 232.mmf 51.qbt 123.ppa 46.hgz 1.pnw %140>]>val=<1.vde [* [our=@p now=@da eny=@uvJ] <17.ayh 34.ygp 14.usy 54.fbg 77.kga 232.mmf 51.qbt 123.ppa 46.hgz 1.pnw %140>]>]<17.ayh 34.ygp 14.usy 54.fbg 77.kga 232.mmf 51.qbt 123.ppa 46.hgz 1.pnw %140>]>]>
Here are the core's arms:
> (sloe -:!>(((on @ @) gth)))~[%run%del%get%apt%dip%has%all%gas%pry%nip%lot%tab%tap%bap%ram%got%any%pop%uni%put]
++all:on
Apply logical AND boolean test on all items.
Accepts
a is a mop.
b is a gate of the type $-([key val] ?), where the type of key and val match those of the mop.
Produces
A ?.
Source
++ all~/ %all|= [a=(tree item) b=$-(item ?)]^- ?|-?~ a&?&((b n.a) $(a l.a) $(a r.a))
Examples
> =myon ((on @ @) gth)> =mymop (gas:myon *((mop @ @) gth) 1^1 2^2 3^3 ~)> (all:myon mymop |=([key=@ val=@] (gte 3 val)))%.y> (all:myon mymop |=([key=@ val=@] (gte 2 val)))%.n
++any:on
Apply logical OR boolean test on all items.
Accepts
a is a mop.
b is a gate of the type $-([key val] ?), where the type of key and val match those of the mop.
Produces
A ?.
Source
++ any~/ %any|= [a=(tree item) b=$-(item ?)]|- ^- ??~ a|?|((b n.a) $(a l.a) $(a r.a))
Examples
> =myon ((on @ @) gth)> =mymop (gas:myon *((mop @ @) gth) 1^1 2^2 3^3 ~)> (any:myon mymop |=([key=@ val=@] =(1 val)))%.y> (any:myon mymop |=([key=@ val=@] =(4 val)))%.n
++apt:on
Verify horizontal and vertical orderings.
Accepts
a is a mop.
Produces
A ?.
Source
++ apt~/ %apt|= a=(tree item)=| [l=(unit key) r=(unit key)]|- ^- ??~ a %.y?& ?~(l %.y (compare key.n.a u.l))?~(r %.y (compare u.r key.n.a))?~(l.a %.y &((mor key.n.a key.n.l.a) $(a l.a, l `key.n.a)))?~(r.a %.y &((mor key.n.a key.n.r.a) $(a r.a, r `key.n.a)))==
Examples
Incorrect order:
> =mymap (malt 1^1 2^2 3^3 ~)> =myon ((on @ @) gth)> (apt:myon mymap)%.n
Correct order:
> =mymop (gas:myon *((mop @ @) gth) 1^1 2^2 3^3 ~)> (apt:myon mymop)%.y
++bap:on
Convert to list, right to left
Accepts
a is a mop.
Produces
A (list [key val]), where key and val are the types of the keys and values in the mop.
Source
++ bap~/ %bap|= a=(tree item)^- (list item)=| b=(list item)|- ^+ b?~ a b$(a r.a, b [n.a $(a l.a)])
Examples
> =myon ((on @ @) gth)> =mymop (gas:myon *((mop @ @) gth) 1^1 2^2 3^3 ~)> mymop{[key=3 val=3] [key=2 val=2] [key=1 val=1]}> (bap:myon mymop)~[[key=1 val=1] [key=2 val=2] [key=3 val=3]]
++del:on
Delete an item from a mop if it exists, producing its value if it's deleted, and a new mop.
Accepts
a is a mop.
b is a noun, the type of the keys in a.
Produces
A cell of a (unit val) and a mop.
Source
++ del~/ %del|= [a=(tree item) =key]^- [(unit val) (tree item)]?~ a [~ ~]?: =(key key.n.a)[`val.n.a (nip a)]?: (compare key key.n.a)=+ [found lef]=$(a l.a)[found a(l lef)]=+ [found rig]=$(a r.a)[found a(r rig)]
Examples
> =myon ((on @ @) gth)> =mymop (gas:myon *((mop @ @) gth) 1^1 2^2 3^3 ~)> (del:myon mymop 2)[[~ 2] {[key=3 val=3] [key=1 val=1]}]> (del:myon mymop 4)[~ {[key=3 val=3] [key=2 val=2] [key=1 val=1]}]
+dip:on
Stateful partial inorder traversal
Mutates state on each run of gate f. Traverses from left to right. Stops when f produces stop=%.y, or else runs all the way to the end. Each run of f can replace an item's value or delete the item.
Accepts
++dip is a wet gate that takes state, which is a mold. The wet gate produces a dry gate that takes:
- ais a- mop.
- stateis the initial value for the state.
- fis a gate of the type- $-([state item] [(unit val) stop=? state]). It takes a pair of the current state and a key-value pair from the- mop. It produces a triple of:- (unit val)a new value for the current item. If it is null, the item is deleted. If you don't want to modify the value, you just give it back the same one you received.
- stopis- .yif traversal should end here, and- .nif it should continue.
- stateis a new value for the- state.
 
Produces
A cell of the final state and the new, possibly modified, mop.
Source
++ dip~/ %dip|* state=mold|= $: a=(tree item)=statef=$-([state item] [(unit val) ? state])==^+ [state a]=/ acc [stop=`?`%.n state=state]=< abet =< main|%++ this .++ abet [state.acc a]++ main^+ this?: =(~ a) this?: stop.acc this=. this left?: stop.acc this=^ del this node=? this !stop.acc right=? a del (nip a)this++ node^+ [del=*? this]?> ?=(^ a)=^ res acc (f state.acc n.a)?~ res[del=& this][del=| this(val.n.a u.res)]++ left^+ this?~ a this=/ lef main(a l.a)lef(a a(l a.lef))++ right^+ this?~ a this=/ rig main(a r.a)rig(a a(r a.rig))--
Examples
> =myon ((on @ @) gth)> =mymop (gas:myon *((mop @ @) gth) 1^1 2^2 3^3 4^4 5^5 ~)
Add them all up:
> ((dip:myon @) mymop 0 |=([stat=@ k=@ v=@] [`v .n (add stat v)]))[15 {[key=5 val=5] [key=4 val=4] [key=3 val=3] [key=2 val=2] [key=1 val=1]}]
Add them up, stopping when the key is less than 3:
> ((dip:myon @) mymop 0 |=([stat=@ k=@ v=@] [`v (lth 3 k) (add stat v)]))[5 {[key=5 val=5] [key=4 val=4] [key=3 val=3] [key=2 val=2] [key=1 val=1]}]
Delete items less than three:
> ((dip:myon @) mymop 0 |=([stat=@ k=@ v=@] [?:((lth k 3) ~ `v) .n (add stat v)]))[15 {[key=5 val=5] [key=4 val=4] [key=3 val=3]}]
++gas:on
Put a list of key-value pairs in a mop.
Accepts
a is a mop.
b is a list of key-value pairs, whose types match those of the mop.
Source
++ gas~/ %gas|= [a=(tree item) b=(list item)]^- (tree item)?~ b a$(b t.b, a (put a i.b))
Examples
> =myon ((on @ @) gth)> (gas:myon *((mop @ @) gth) 1^1 2^2 3^3 4^4 5^5 ~){[key=5 val=5] [key=4 val=4] [key=3 val=3] [key=2 val=2] [key=1 val=1]}
++get:on
Get a value at a key or null
Accepts
a is a mop.
b is a noun whose type matches that of the mop's keys.
Produces
A (unit val), where val is the type of the values of the mop.
Source
++ get~/ %get|= [a=(tree item) b=key]^- (unit val)?~ a ~?: =(b key.n.a)`val.n.a?: (compare b key.n.a)$(a l.a)$(a r.a)
Examples
> =myon ((on @ @) gth)> =mymop (gas:myon *((mop @ @) gth) 1^1 2^2 3^3 4^4 5^5 ~)> (get:myon mymop 3)[~ 3]> (get:myon mymop 7)~
++got:on
Get a value at a key, crashing if it doesn't exist
Accepts
a is a mop.
b is a noun whose type matches that of the mop's keys.
Produces
A noun of the type of the values of the mop, crashing if the key doesn't exist.
Source
++ got|= [a=(tree item) b=key]^- val(need (get a b))
Examples
> =myon ((on @ @) gth)> =mymop (gas:myon *((mop @ @) gth) 1^1 2^2 3^3 4^4 5^5 ~)> (got:myon mymop 3)3> (got:myon mymop 7)dojo: hoon expression failed
++has:on
Check for key existence
Accepts
a is a mop.
b is a noun whose type matches that of the mop's keys.
Produces
A ?.
Source
++ has~/ %has|= [a=(tree item) b=key]^- ?!=(~ (get a b))
Examples
> =myon ((on @ @) gth)> =mymop (gas:myon *((mop @ @) gth) 1^1 2^2 3^3 4^4 5^5 ~)> (has:myon mymop 3)%.y> (has:myon mymop 7)%.n
++lot:on
Take a subset range excluding start and/or end, and all elements outside the range.
Accepts
tre is a mop.
start is a (unit key), where key is a noun whose type matches the type of the mop keys. If non-null, this item and all those previous will be excluded.
end is a (unit key), where key is a noun whose type matches the type of the mop keys. If non-null, this item and all those after will be excluded.
Produces
A mop.
Source
++ lot~/ %lot|= $: tre=(tree item)start=(unit key)end=(unit key)==^- (tree item)|^?: ?&(?=(~ start) ?=(~ end))tre?~ start(del-span tre %end end)?~ end(del-span tre %start start)?> (compare u.start u.end)=. tre (del-span tre %start start)(del-span tre %end end)::++ del-span|= [a=(tree item) b=?(%start %end) c=(unit key)]^- (tree item)?~ a a?~ c a?- b%start?: =(key.n.a u.c)(nip a(l ~))?: (compare key.n.a u.c)$(a (nip a(l ~)))a(l $(a l.a))::%end?: =(u.c key.n.a)(nip a(r ~))?: (compare key.n.a u.c)a(r $(a r.a))$(a (nip a(r ~)))==--
Examples
> =myon ((on @ @) lth)> =mymop (gas:myon *((mop @ @) lth) 2^2 4^4 6^6 8^8 10^10 ~)> mymop{[key=2 val=2] [key=4 val=4] [key=6 val=6] [key=8 val=8] [key=10 val=10]}> (lot:myon mymop `3 ~){[key=4 val=4] [key=6 val=6] [key=8 val=8] [key=10 val=10]}> (lot:myon mymop `4 ~){[key=6 val=6] [key=8 val=8] [key=10 val=10]}> (lot:myon mymop ~ `8){[key=2 val=2] [key=4 val=4] [key=6 val=6]}> (lot:myon mymop `3 `7){[key=4 val=4] [key=6 val=6]}> (lot:myon mymop ~ ~){[key=2 val=2] [key=4 val=4] [key=6 val=6] [key=8 val=8] [key=10 val=10]}> (lot:myon mymop `0 `100){[key=2 val=2] [key=4 val=4] [key=6 val=6] [key=8 val=8] [key=10 val=10]}
++nip:on
Remove root (for internal use)
Accepts
a is a mop.
Produces
A mop.
Source
++ nip~/ %nip|= a=(tree item)^- (tree item)?> ?=(^ a)|- ^- (tree item)?~ l.a r.a?~ r.a l.a?: (mor key.n.l.a key.n.r.a)l.a(r $(l.a r.l.a))r.a(l $(r.a l.r.a))
Examples
Note this is for internal use, you would not normally use ++nip.
> =myon ((on @ @) gth)> =mymop (gas:myon *((mop @ @) gth) 1^1 2^2 3^3 ~)> mymop{[key=3 val=3] [key=2 val=2] [key=1 val=1]}> (nip:myon mymop){[key=3 val=3] [key=1 val=1]}
++pop:on
Produce head (the leftmost item) and rest or crash if empty
Accepts
a is a mop.
Produces
A cell of head, the leftmost item, and rest, the mop sans its leftmost item. If the mop was empty, it'll crash.
Source
++ pop~/ %pop|= a=(tree item)^- [head=item rest=(tree item)]?~ a !!?~ l.a [n.a r.a]=/ l $(a l.a):- head.l?: |(?=(~ rest.l) (mor key.n.a key.n.rest.l))a(l rest.l)rest.l(r a(r r.rest.l))
Examples
> =myon ((on @ @) gth)> =mymop (gas:myon *((mop @ @) gth) 1^1 2^2 3^3 ~)> mymop{[key=3 val=3] [key=2 val=2] [key=1 val=1]}> (pop:myon mymop)[head=[key=3 val=3] rest={[key=2 val=2] [key=1 val=1]}]> (pop:myon *((mop @ @) gth))dojo: hoon expression failed
++pry:on
Produce the head (leftmost item) or null
Accepts
a is a mop.
Produces
A (unit item), where item is a key-value pair. The unit is null if the mop was empty.
Source
++ pry~/ %pry|= a=(tree item)^- (unit item)?~ a ~|-?~ l.a `n.a$(a l.a)
Examples
> =myon ((on @ @) gth)> =mymop (gas:myon *((mop @ @) gth) 1^1 2^2 3^3 ~)> (pry:myon mymop)[~ [key=3 val=3]]> (pry:myon *((mop @ @) gth))~
++put:on
Insert an item
Accepts
a is a mop.
key is a noun whose type matches the keys in a.
val is a noun whose type matches the values in a.
Produces
A mop.
Source
++ put~/ %put|= [a=(tree item) =key =val]^- (tree item)?~ a [n=[key val] l=~ r=~]?: =(key.n.a key) a(val.n val)?: (compare key key.n.a)=/ l $(a l.a)?> ?=(^ l)?: (mor key.n.a key.n.l)a(l l)l(r a(l r.l))=/ r $(a r.a)?> ?=(^ r)?: (mor key.n.a key.n.r)a(r r)r(l a(r l.r))
Examples
> =myon ((on @ @) gth)> =mymop (gas:myon *((mop @ @) gth) 1^1 2^2 3^3 ~)> (put:myon mymop 7 7){[key=7 val=7] [key=3 val=3] [key=2 val=2] [key=1 val=1]}
++ram:on
Produce tail (rightmost item) or null
Accepts
a is a mop.
Produces
A (unit item) where item is a key-value pair whose type is that of the keys and values in the mop.
Source
++ ram~/ %ram|= a=(tree item)^- (unit item)?~ a ~|-?~ r.a `n.a$(a r.a)
Examples
> =myon ((on @ @) gth)> =mymop (gas:myon *((mop @ @) gth) 1^1 2^2 3^3 ~)> mymop{[key=3 val=3] [key=2 val=2] [key=1 val=1]}> (ram:myon mymop)[~ [key=1 val=1]]> (ram:myon *((mop @ @) gth))~
++run:on
Apply gate to transform all values in place
Accepts
a is a mop.
b is a gate of $-(val *), where val is the type of the values in the mop.
Produces
A mop.
Source
++ run~/ %run|* [a=(tree item) b=$-(val *)]|-?~ a a[n=[key.n.a (b val.n.a)] l=$(a l.a) r=$(a r.a)]
Examples
> =myon ((on @ @) gth)> =mymop (gas:myon *((mop @ @) gth) 1^1 2^2 3^3 ~)> mymop{[key=3 val=3] [key=2 val=2] [key=1 val=1]}> `((mop @ @) gth)`(run:myon mymop succ){[key=3 val=4] [key=2 val=3] [key=1 val=2]}> `((mop @ @t) gth)`(run:myon mymop (cury add 'a')){[key=3 val='d'] [key=2 val='c'] [key=1 val='b']}
++tab:on
Tabulate a subset with a max count, maybe starting after a certain element.
Accepts
a is a mop.
b is a (unit key). The type of key matches the type of keys in the mop. This specifies where to start if non-null.
c is a @ specifying the maximum number of items to return.
Produces
A (list item), where item is a key-value matching the type of the mop.
Source
++ tab~/ %tab|= [a=(tree item) b=(unit key) c=@]^- (list item)|^(flop e:(tabulate (del-span a b) b c))::++ tabulate|= [a=(tree item) b=(unit key) c=@]^- [d=@ e=(list item)]?: ?&(?=(~ b) =(c 0))[0 ~]=| f=[d=@ e=(list item)]|- ^+ f?: ?|(?=(~ a) =(d.f c)) f=. f $(a l.a)?: =(d.f c) f=. f [+(d.f) [n.a e.f]]?:(=(d.f c) f $(a r.a))::++ del-span|= [a=(tree item) b=(unit key)]^- (tree item)?~ a a?~ b a?: =(key.n.a u.b)r.a?: (compare key.n.a u.b)$(a r.a)a(l $(a l.a))--
Examples
> =myon ((on @ @) gth)> =mymop (gas:myon *((mop @ @) gth) 1^1 2^2 3^3 4^4 5^5 ~)> mymop{[key=5 val=5] [key=4 val=4] [key=3 val=3] [key=2 val=2] [key=1 val=1]}> (tab:myon mymop ~ 2)~[[key=5 val=5] [key=4 val=4]]> (tab:myon mymop `4 2)~[[key=3 val=3] [key=2 val=2]]> (tab:myon mymop `4 100)~[[key=3 val=3] [key=2 val=2] [key=1 val=1]]
+tap:on
Convert to list, left to right
Accepts
a is a mop.
Produces
A (list item), where item is a key-value pair whose type matches those of the mop.
Source
++ tap~/ %tap|= a=(tree item)^- (list item)=| b=(list item)|- ^+ b?~ a b$(a l.a, b [n.a $(a r.a)])
Examples
> =myon ((on @ @) gth)> =mymop (gas:myon *((mop @ @) gth) 1^1 2^2 3^3 4^4 5^5 ~)> mymop{[key=5 val=5] [key=4 val=4] [key=3 val=3] [key=2 val=2] [key=1 val=1]}> (tap:myon mymop)~[[key=5 val=5] [key=4 val=4] [key=3 val=3] [key=2 val=2] [key=1 val=1]]
++uni:on
Unify two ordered maps
If the keys overlap and the values are different, the value in mop b take precedence over the value in mop a.
Accepts
a is a mop.
b is a mop.
Produces
A mop.
Source
++ uni~/ %uni|= [a=(tree item) b=(tree item)]^- (tree item)?~ b a?~ a b?: =(key.n.a key.n.b)[n=n.b l=$(a l.a, b l.b) r=$(a r.a, b r.b)]?: (mor key.n.a key.n.b)?: (compare key.n.b key.n.a)$(l.a $(a l.a, r.b ~), b r.b)$(r.a $(a r.a, l.b ~), b l.b)?: (compare key.n.a key.n.b)$(l.b $(b l.b, r.a ~), a r.a)$(r.b $(b r.b, l.a ~), a l.a)--
Examples
> =myon ((on @ @) gth)> =a (gas:myon *((mop @ @) gth) 1^1 2^2 3^3 4^4 5^5 ~)> =b (gas:myon *((mop @ @) gth) 2^20 4^40 6^60 ~)> (uni:myon a b){[key=6 val=60] [key=5 val=5] [key=4 val=40] [key=3 val=3] [key=2 val=20] [key=1 val=1]}