urbit/lib/trad.hoon
2019-05-23 12:31:52 -07:00

143 lines
3.6 KiB
Plaintext

|* [input-type=mold card-type=mold]
|%
+$ trad-input (unit input-type)
+$ trad-move (pair bone card-type)
::
:: notes: notes to send immediately. These will go out even if a
:: later stage of the process fails, so they shouldn't have any
:: semantic effect on the rest of the system. Path is
:: included exclusively for documentation and |verb.
:: effects: moves to send after the process ends.
:: wait: don't move on, stay here. The next sign should come back
:: to this same callback.
:: cont: continue process with new callback.
:: fail: abort process; don't send effects
:: done: finish process; send effects
::
++ trad-output-raw
|* a=mold
$~ [~ ~ %done *a]
$: notes=(list [path card-type])
effects=(list card-type)
$= next
$% [%wait ~]
[%cont self=(trad-form-raw a)]
[%fail err=(pair term tang)]
[%done value=a]
==
==
::
++ trad-form-raw
|* a=mold
$-(trad-input (trad-output-raw a))
::
++ trad-fail
|= err=(pair term tang)
|= trad-input
[~ ~ %fail err]
::
++ trad
|* a=mold
|%
++ output (trad-output-raw a)
++ form (trad-form-raw a)
++ pure
|= arg=a
^- form
|= trad-input
[~ ~ %done arg]
::
++ bind
|* b=mold
|= [m-b=(trad-form-raw b) fun=$-(b form)]
^- form
|= input=trad-input
=/ b-res=(trad-output-raw b)
(m-b input)
^- output
:+ notes.b-res effects.b-res
?- -.next.b-res
%wait [%wait ~]
%cont [%cont ..$(m-b self.next.b-res)]
%fail [%fail err.next.b-res]
%done [%cont (fun value.next.b-res)]
==
::
:: The trad monad must be evaluted in a particular way to maintain
:: its monadic character. +take:eval implements this.
::
++ eval
|%
:: Indelible state of a trad
::
+$ eval-form
$: effects=(list card-type)
=form
==
::
:: Convert initial form to eval-form
::
++ from-form
|= =form
^- eval-form
[~ form]
::
:: The cases of results of +take
::
+$ eval-result
$% [%next ~]
[%fail err=(pair term tang)]
[%done value=a]
==
::
:: Take a new sign and run the trad against it
::
++ take
:: moves: accumulate throughout recursion the moves to be
:: produced now
=| moves=(list trad-move)
|= [=eval-form =bone =our=wire =trad-input]
^- [[(list trad-move) =eval-result] _eval-form]
:: run the trad callback
::
=/ =output (form.eval-form trad-input)
:: add notes to moves
::
=. moves
%+ welp
moves
%+ turn notes.output
|= [=path card=card-type]
^- trad-move
[bone card]
:: add effects to list to be produced when done
::
=. effects.eval-form
(weld effects.eval-form effects.output)
:: if done, produce effects
::
=? moves ?=(%done -.next.output)
%+ welp
moves
%+ turn effects.eval-form
|= card=card-type
^- trad-move
[bone card]
:: case-wise handle next steps
::
?- -.next.output
%wait [[moves %next ~] eval-form]
%fail [[moves %fail err.next.output] eval-form]
%done [[moves %done value.next.output] eval-form]
%cont
:: recurse to run continuation with initialization input
::
%_ $
form.eval-form self.next.output
trad-input ~
==
==
--
--
--