!import "../../lib/base.tri" !Local !import "../../lib/io.tri" !Local !import "../../lib/socket.tri" !Local -- Preserve the host-driver Result shape on error, run okCase on success. onOk = action okCase : bind action (result : matchResult (err rest : pure result) okCase result) -- Convenience: print a string and continue. printLn = s : bind (putStr (append s "\n")) (_ : pure t) -- Main accept+echo loop. Recursion via y. echoLoop = y (self server : bind (accept server) (acceptResult : matchResult (err rest : bind (printLn (append "accept error: " err)) (_ : self server)) (accepted rest : matchPair (clientSock addr : bind (printLn (append "client from " addr)) (_ : bind (recv clientSock 4096) (msgResult : matchResult (err rest : bind (closeSocket clientSock) (_ : self server)) (msg rest : bind (send clientSock msg) (_ : bind (closeSocket clientSock) (_ : self server))) msgResult))) accepted) acceptResult)) main = io ( onOk socket (server rest : onOk (bindSocket server "127.0.0.1" 0) (_ rest : onOk (listen server 5) (_ rest : onOk (getSocketName server) (port rest : bind (printLn (append "Echo server listening on port " (showNumber port))) (_ : echoLoop server))))))