Mips (Maps of Maps)

A +mip is a map of maps. These can be constructed manually by nesting ordinary +maps, but the %landscape desk contains a /lib/mip.hoon library which makes these a bit easier to deal with. You can copy the library into your own project. The various +mip functions are documented below.

+mip

Mip (map of maps) mold builder

A +mip is a map of maps. An outer +map maps keys to inner +maps, which themselves map keys to values.

A (mip kex key value) is equivalent to (map kex (map key value)).

Accepts

kex is a $mold, the type of the outer map's key.

key is a $mold, the type of the key of the inner maps.

value is a $mold, the type of the value of the inner maps.

Produces

A $mold.

Source

|%
++  mip                                                 ::  map of maps
  |$  [kex key value]
  (map kex (map key value))

Examples

> =libmip -build-file /=landscape=/lib/mip/hoon

> *(mip:libmip @ @ @)
{}

> (~(put bi:libmip *(mip:libmip @ @ @)) 1 2 3) 
[n=[p=1 q=[n=[p=2 q=3] l=~ r=~]] l=~ r=~]

+bi

Mip engine

This is the container door for all the mip functions.

Accepts

.a is a +mip.

Source

++  bi                                                  ::  mip engine
  =|  a=(map * (map))
  |@

Examples

> =libmip -build-file /=landscape=/lib/mip/hoon

> ~(. bi:libmip *(mip:libmip @ @ @))
< 8.bql
  [ a=nlr([p=@ q=nlr([p=@ q=@])])
    <2.gtk 17.zfg 35.yza 14.oai 54.ecl 77.swa 232.sje 51.qbt 123.ppa 46.hgz 1.pnw %140>
  ]
>

+del:bi

Delete item in +mip

This takes two keys as its argument, .b and .c, and deletes .c in the inner map that matches key .b in the outer map . If this results in an empty inner map, then .b is also deleted from the outer map.

Accepts

.a is a +mip, and is the +bi door's sample.

.b is a key matching the key type of the outer map.

.c is a key matching the key type of the inner maps.

Produces

A +mip with .c deleted from .b, or .b deleted from .a if .c ended up empty.

Source

++  del
  |*  [b=* c=*]
  =+  d=(~(gut by a) b ~)
  =+  e=(~(del by d) c)
  ?~  e
    (~(del by a) b)
  (~(put by a) b e)

Examples

> =libmip -build-file /=landscape=/lib/mip/hoon

> =mymip (~(put bi:libmip *(mip:libmip @ @ @)) 1 2 3)
> =mymip (~(put bi:libmip mymip) 1 3 4)

> mymip
[n=[p=1 q=[n=[p=2 q=3] l=~ r=[n=[p=3 q=4] l=~ r=~]]] l=~ r=~]

> =mymip (~(del bi:libmip mymip) 1 2)

> mymip
[n=[p=1 q=[n=[p=3 q=4] l=~ r=~]] l=~ r=~]

> =mymip (~(del bi:libmip mymip) 1 3)

> mymip
~

+get:bi

Maybe get value in +mip

Get the value of .c in the map with key .b in +mip .a as a unit. If there's no .c in .b or .b in .a, the unit is null.

Accepts

.a is a +mip, and is the sample of the +bi door.

.b is a key matching the key type of the outer map.

.c is a key matching the key type of the inner maps.

Produces

A (unit [type]), where [type] is the value type. The unit is null if there's no .c in .b or no .b in .a.

Source

++  get
  |*  [b=* c=*]
  =>  .(b `_?>(?=(^ a) p.n.a)`b, c `_?>(?=(^ a) ?>(?=(^ q.n.a) p.n.q.n.a))`c)
  ^-  (unit _?>(?=(^ a) ?>(?=(^ q.n.a) q.n.q.n.a)))
  (~(get by (~(gut by a) b ~)) c)

Examples

> =libmip -build-file /=landscape=/lib/mip/hoon

> =mymip (~(put bi:libmip *(mip:libmip @ @ @)) 1 2 3)

> (~(get bi:libmip mymip) 1 2)
[~ 3]

> (~(get bi:libmip mymip) 2 3)
~

+got:bi

Get value in +mip or crash

Get the value of .c in the map with key .b in +mip .a. If there's no .c in .b or .b in .a, crash.

Accepts

.a is a +mip, and is the sample of the +bi door.

.b is a key matching the key type of the outer map.

.c is a key matching the key type of the inner maps.

Produces

A noun of the type of the values in the +mip, or else crashes.

Source

++  got
  |*  [b=* c=*]
  (need (get b c))

Examples

> =libmip -build-file /=landscape=/lib/mip/hoon

> =mymip (~(put bi:libmip *(mip:libmip @ @ @)) 1 2 3)

> (~(got bi:libmip mymip) 1 2)
3

> (~(got bi:libmip mymip) 2 3)
/lib/mip/hoon:<[25 5].[25 21]>
dojo: hoon expression failed

+gut:bi

Get value in +mip or default

Get the value of .c in the map with key .b in +mip .a. If there's no .c in .b or .b in .a, produce default value .d.

Accepts

.a is a +mip, and is the sample of the +bi door.

.b is a key matching the key type of the outer map.

.c is a key matching the key type of the inner maps.

.d is a default value, which is produced if the value cannot be found.

Produces

A noun, either the type of the value in the map or .d.

Source

++  gut
  |*  [b=* c=* d=*]
  (~(gut by (~(gut by a) b ~)) c d)

Examples

> =libmip -build-file /=landscape=/lib/mip/hoon

> =mymip (~(put bi:libmip *(mip:libmip @ @ @)) 1 2 3)

> (~(gut bi:libmip mymip) 1 2 42)
3

> (~(gut bi:libmip mymip) 2 3 42)
42

+has:bi

Check if +mip contains

Check if +mip .a contains .c in .b.

Accepts

.a is a +mip, and is the sample of the +bi door.

.b is a key matching the key type of the outer map.

.c is a key matching the key type of the inner maps.

Produces

A ? which is true if .c in .b exists, and false otherwise.

Source

++  has
  |*  [b=* c=*]
  !=(~ (get b c))

Examples

> =libmip -build-file /=landscape=/lib/mip/hoon

> =mymip (~(put bi:libmip *(mip:libmip @ @ @)) 1 2 3)

> (~(has bi:libmip mymip) 1 2)
%.y

> (~(has bi:libmip mymip) 2 3)
%.n

+key:bi

Get keys of inner map in +mip

Get the +set of keys of the inner map matching key .b in the outer map. If .b doesn't exist, an empty set is returned.

Accepts

.a is a +mip, and is the sample of the +bi door.

.b is a key matching the key type of the outer map.

Produces

A (set [type]) where [type] is the type of the keys in the inner map.

Source

++  key
  |*  b=*
  ~(key by (~(gut by a) b ~))

Examples

> =libmip -build-file /=landscape=/lib/mip/hoon

> =mymip (~(put bi:libmip *(mip:libmip @ @ @)) 1 2 3)

> (~(key bi:libmip mymip) 1)
{2}

> (~(key bi:libmip mymip) 2)
{}

+put:bi

Insert value in +mip

Add value .d with key .c to the inner map with key .b in the outer map. If .b doesn't exist, an inner map is also added with that key. If .c already exists, its value is replaced with .d.

Accepts

.a is a +mip, and is the sample of the +bi door.

.b is a key matching the key type of the outer map.

.c is a key matching the key type of the inner maps.

.d is a noun matching the type of the values in the +mip.

Produces

A new, modified +mip.

Source

++  put
  |*  [b=* c=* d=*]
  %+  ~(put by a)  b
  %.  [c d]
  %~  put  by
  (~(gut by a) b ~)

Examples

> =libmip -build-file /=landscape=/lib/mip/hoon

> =mymip (~(put bi:libmip *(mip:libmip @ @ @)) 1 2 3)
> =mymip (~(put bi:libmip mymip) 1 1 42)
> =mymip (~(put bi:libmip mymip) 2 12 99)

> ~(tap bi:libmip mymip)
~[[x=2 y=12 v=99] [x=1 y=2 v=3] [x=1 y=1 v=42]]

+tap:bi

Convert +mip to +list

The +mip is flattened to a +list of the triple [x y v], where .x is a key in the outer map, .y is a key in an inner map, and .v is its value.

Accepts

.a is a +mip, and is the sample of the +bi door.

Produces

A triple cell of [x y v], where:

  • .x is a key in the outer map.

  • .y is a key in an inner map.

  • .v is its value.

Source

++  tap
  ::NOTE  naive turn-based implementation find-errors ):
  =<  $
  =+  b=`_?>(?=(^ a) *(list [x=_p.n.a _?>(?=(^ q.n.a) [y=p v=q]:n.q.n.a)]))`~
  |.  ^+  b
  ?~  a
    b
  $(a r.a, b (welp (turn ~(tap by q.n.a) (lead p.n.a)) $(a l.a)))
--

Examples

> =libmip -build-file /=landscape=/lib/mip/hoon

> =mymip (~(put bi:libmip *(mip:libmip @ @ @)) 1 2 3)
> =mymip (~(put bi:libmip mymip) 1 1 42)
> =mymip (~(put bi:libmip mymip) 2 12 99)

> ~(tap bi:libmip mymip)
~[[x=2 y=12 v=99] [x=1 y=2 v=3] [x=1 y=1 v=42]]

Last updated