59 lines
2.2 KiB
Plaintext
59 lines
2.2 KiB
Plaintext
!import "../lib/base.tri" !Local
|
|
!import "../lib/list.tri" !Local
|
|
!import "../lib/io.tri" !Local
|
|
|
|
-- Interaction Tree Effect Runtime
|
|
--
|
|
-- The IO system is an interaction-tree effect runtime interpreted by a
|
|
-- small-step machine with a cooperative scheduler. Primitive actions
|
|
-- (putStr, readFile, writeFile, ...) are tagged nodes in an interaction
|
|
-- tree. Sequencing is performed by the single generic `bind` constructor.
|
|
--
|
|
-- pure x -- lift a pure value into IO
|
|
-- bind action k -- run action, then apply k to its result
|
|
-- thenIO a b -- run a, discard its result, then run b
|
|
-- mapIO action f -- run action, then apply f to its result inside pure
|
|
--
|
|
-- The runtime supports several effects beyond basic IO:
|
|
-- ask -- read the current environment
|
|
-- local f action -- run action with environment transformed by f
|
|
-- get -- read the current mutable state
|
|
-- put s -- replace the mutable state
|
|
-- fork action -- spawn a concurrent task, returning a handle
|
|
-- await handle -- wait for a forked task to complete
|
|
-- yield -- yield control to the scheduler
|
|
-- sleep ms -- suspend current task for N milliseconds
|
|
--
|
|
-- File operations return a Result tree (see lib/base.tri):
|
|
-- ok value -- pair true (pair value t)
|
|
-- err code -- pair false (pair code t)
|
|
--
|
|
-- Use onReadFile / onWriteFile for convenient branching.
|
|
--
|
|
-- See demos/interactionTrees/ for smaller focused examples.
|
|
|
|
-- Cooperative async demo.
|
|
-- fork runs an action in the background.
|
|
-- sleep suspends the current task for N milliseconds.
|
|
-- await waits for a forked task and returns its value.
|
|
--
|
|
-- Here the child sleeps for 2 s while the parent prints immediately.
|
|
-- The parent's message appears first, proving interleaving.
|
|
|
|
asyncDemo = (
|
|
bind (fork
|
|
(bind (sleep 2000) (_ :
|
|
bind (putStrLn "2000ms done sleeping!") (_ :
|
|
pure "child2000 done"))))
|
|
(handle2000 :
|
|
bind (fork
|
|
(bind (sleep 5000) (_ :
|
|
bind (putStrLn "5000ms done sleeping!") (_ :
|
|
pure "child5000 done"))))
|
|
(handle5000 :
|
|
bind (putStrLn "Parent first!") (_ :
|
|
bind (await handle5000) (_ :
|
|
await handle2000)))))
|
|
|
|
main = io asyncDemo
|