interactionTrees.tri (2204B)
1 !import "prelude" !Local 2 !import "io" !Local 3 4 -- Interaction Tree Effect Runtime 5 -- 6 -- The IO system is an interaction-tree effect runtime interpreted by a 7 -- small-step machine with a cooperative scheduler. Primitive actions 8 -- (putStr, readFile, writeFile, ...) are tagged nodes in an interaction 9 -- tree. Sequencing is performed by the single generic `bind` constructor. 10 -- 11 -- pure x -- lift a pure value into IO 12 -- bind action k -- run action, then apply k to its result 13 -- thenIO a b -- run a, discard its result, then run b 14 -- mapIO action f -- run action, then apply f to its result inside pure 15 -- 16 -- The runtime supports several effects beyond basic IO: 17 -- ask -- read the current environment 18 -- local f action -- run action with environment transformed by f 19 -- get -- read the current mutable state 20 -- put s -- replace the mutable state 21 -- fork action -- spawn a concurrent task, returning a handle 22 -- await handle -- wait for a forked task to complete 23 -- yield -- yield control to the scheduler 24 -- sleep ms -- suspend current task for N milliseconds 25 -- 26 -- File operations return a Result tree (see lib/base.tri): 27 -- ok value -- pair true (pair value t) 28 -- err msg -- pair false (pair msg t) 29 -- 30 -- Use onReadFile / onWriteFile for convenient branching. 31 -- 32 -- See demos/interactionTrees/ for smaller focused examples. 33 34 -- Cooperative async demo. 35 -- fork runs an action in the background. 36 -- sleep suspends the current task for N milliseconds. 37 -- await waits for a forked task and returns its value. 38 -- 39 -- Here the child sleeps for 2 s while the parent prints immediately. 40 -- The parent's message appears first, proving interleaving. 41 42 asyncDemo = ( 43 bind (fork 44 (bind (sleep 2000) (_ : 45 bind (putStrLn "2000ms done sleeping!") (_ : 46 pure "child2000 done")))) 47 (handle2000 : 48 bind (fork 49 (bind (sleep 5000) (_ : 50 bind (putStrLn "5000ms done sleeping!") (_ : 51 pure "child5000 done")))) 52 (handle5000 : 53 bind (putStrLn "Parent first!") (_ : 54 bind (await handle5000) (_ : 55 await handle2000))))) 56 57 main = io asyncDemo