:: 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: :: :: (cork pure (curr bind f)) = f :: (bind m pure) = m :: ((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. :: /- aquarium =, aquarium |% +$ ph-input [now=@da who=ship uf=unix-effect] :: ++ 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)) :: ++ ph |* a=mold |% ++ output (ph-output-raw a) ++ form (ph-form-raw a) ++ pure |= arg=a ^- form |= ph-input [& ~ %done arg] :: ++ bind |* b=mold |= [m-b=(ph-form-raw b) fun=$-(b form)] ^- form |= input=ph-input =/ b-res=(ph-output-raw b) (m-b input) ^- output :+ thru.b-res events.b-res ?- -.next.b-res %wait [%wait ~] %cont [%cont ..$(m-b self.next.b-res)] %fail [%fail ~] %done [%cont (fun value.next.b-res)] == -- --