shrub/pkg/arvo/lib/ph.hoon

87 lines
2.4 KiB
Plaintext
Raw Normal View History

2019-04-20 04:00:39 +03:00
:: Defines the ph monad.
::
:: A complete ph test has type data:(ph ,~). This is a function that
:: accepts a new unix-effect and produces a list of ph-events to inject
:: back into the system. It also produces one of four "next steps":
::
:: %wait: no change; on next unix-effect call this same function.
:: %cont: swap out this test for another one. Mainly useful for
:: the implementation of +bind.
:: %fail: the test has failed.
:: %done: the test has finished successfully.
::
:: When producing %done, you may specify a value. The ph app assumes
:: the value of each whole test will be ~. During the test, though, it
:: may be useful to produce intermediate values.
::
:: We define two additional functions. +return takes a value and
:: produces a test which immediately produces a %done with that value.
::
:: +bind takes a test and a function from the output type of that test
:: to another test. This is useful to link tests together. See
:: lib/ph/tests.hoon for examples of usage.
::
:: You may recognize monad terminology. These functions satisfy the
:: monad laws: If `f` and `g` are the sort of function that go in the
:: second argument to bind and `m` is a test, then:
::
2019-04-23 00:47:25 +03:00
:: (cork pure (curr bind f)) = f
:: (bind m pure) = m
2019-04-20 04:00:39 +03:00
:: ((bind m f) g) = (bind m (bind f g))
::
:: Maintaining these laws requires a particular interpretation of the
:: monad, which the ph app implements in +diff-aqua-effects. Thus,
:: within the ph app the monad laws hold.
2019-02-06 05:21:41 +03:00
::
/- aquarium
=, aquarium
|%
2019-04-13 09:54:30 +03:00
+$ ph-input
2019-04-20 02:29:14 +03:00
[now=@da who=ship uf=unix-effect]
2019-04-13 09:54:30 +03:00
::
2019-04-23 00:47:25 +03:00
++ ph-output-raw
|* a=mold
$~ [& ~ %done *a]
$: thru=?
events=(list ph-event)
$= next
$% [%wait ~]
[%cont self=(ph-form-raw a)]
[%fail ~]
[%done value=a]
==
==
::
++ ph-form-raw
|* a=mold
$-(ph-input (ph-output-raw a))
::
2019-04-13 09:54:30 +03:00
++ ph
|* a=mold
|%
2019-04-23 00:47:25 +03:00
++ output (ph-output-raw a)
++ form (ph-form-raw a)
++ pure
2019-04-13 09:54:30 +03:00
|= arg=a
2019-04-23 00:47:25 +03:00
^- form
2019-04-13 09:54:30 +03:00
|= ph-input
2019-04-20 01:04:50 +03:00
[& ~ %done arg]
2019-04-18 23:52:00 +03:00
::
++ bind
2019-04-13 09:54:30 +03:00
|* b=mold
2019-04-23 00:47:25 +03:00
|= [m-b=(ph-form-raw b) fun=$-(b form)]
^- form
2019-04-13 09:54:30 +03:00
|= input=ph-input
2019-04-18 23:52:00 +03:00
=/ b-res=(ph-output-raw b)
(m-b input)
2019-04-23 00:47:25 +03:00
^- output
2019-04-18 23:52:00 +03:00
:+ thru.b-res events.b-res
?- -.next.b-res
2019-04-20 01:04:50 +03:00
%wait [%wait ~]
%cont [%cont ..$(m-b self.next.b-res)]
%fail [%fail ~]
%done [%cont (fun value.next.b-res)]
2019-04-14 05:51:46 +03:00
==
2019-04-18 23:52:00 +03:00
--
2019-02-06 05:21:41 +03:00
--