I'm deeply satisfied to be building an interaction tree runtime where the interaction trees are themselves computed via and represented by trees. It's trees all the way down.
85 lines
2.5 KiB
Plaintext
85 lines
2.5 KiB
Plaintext
!import "base.tri" !Local
|
|
!import "list.tri" !Local
|
|
!import "conversions.tri" !Local
|
|
|
|
-- IO constructors for host-interpreted interaction trees.
|
|
-- Free-monad style: Bind is the single sequencing mechanism.
|
|
|
|
version = 1
|
|
|
|
io = action : pair "tricuIO" (pair version action)
|
|
|
|
pure = x : pair 0 x
|
|
bind = action k : pair 1 (pair action k)
|
|
|
|
putStr = s : pair 10 s
|
|
getLine = pair 11 t
|
|
|
|
readFile = p : pair 20 p
|
|
writeFile = p c : pair 21 (pair p c)
|
|
|
|
ask = pair 30 t
|
|
local = f action : pair 31 (pair f action)
|
|
|
|
get = pair 40 t
|
|
put = s : pair 41 s
|
|
|
|
fork = action : pair 60 action
|
|
await = handle : pair 61 handle
|
|
yield = pair 62 t
|
|
sleep = ms : pair 63 ms
|
|
|
|
-- ---------------------------------------------------------------------------
|
|
-- Generic sequencing combinators
|
|
-- ---------------------------------------------------------------------------
|
|
|
|
thenIO = a b : bind a (_ : b)
|
|
mapIO = action f : bind action (x : pure (f x))
|
|
|
|
-- ---------------------------------------------------------------------------
|
|
-- Convenience helpers
|
|
-- ---------------------------------------------------------------------------
|
|
|
|
print = s : bind (putStr s) (_ : pure t)
|
|
putStrLn = s : bind (putStr (append s "\n")) (_ : pure t)
|
|
|
|
-- ---------------------------------------------------------------------------
|
|
-- Result-aware file helpers
|
|
-- ---------------------------------------------------------------------------
|
|
|
|
onReadFile = (path errCase okCase :
|
|
bind (readFile path) (result :
|
|
matchResult errCase okCase result))
|
|
|
|
onWriteFile = (path contents errCase okCase :
|
|
bind (writeFile path contents) (result :
|
|
matchResult errCase okCase result))
|
|
|
|
-- ---------------------------------------------------------------------------
|
|
-- Convenience helpers for the common cases
|
|
-- ---------------------------------------------------------------------------
|
|
|
|
readFileOrPrintError = (path okCase :
|
|
onReadFile path
|
|
(err rest : putStrLn "Read failed")
|
|
okCase)
|
|
|
|
writeFileOrPrintError = (path contents okCase :
|
|
onWriteFile path contents
|
|
(err rest : putStrLn "Write failed")
|
|
okCase)
|
|
|
|
copyFile = (src dst :
|
|
bind (readFile src)
|
|
(result :
|
|
matchResult
|
|
(err rest : putStrLn "Read failed")
|
|
(contents rest :
|
|
bind (writeFile dst contents)
|
|
(wr :
|
|
matchResult
|
|
(err rest : putStrLn "Write failed")
|
|
(ok rest : pure t)
|
|
wr))
|
|
result))
|