From 4abfd5413b5a7aa540d7c06b387e3426ff5c532c Mon Sep 17 00:00:00 2001 From: Eduardo Julian Date: Thu, 16 Nov 2017 01:45:40 -0400 Subject: - Added "Process" type for IO operations that can fail. --- stdlib/source/lux/io.lux | 49 ++++++++++++++++++++++------ stdlib/test/test/lux/concurrency/actor.lux | 12 +++---- stdlib/test/test/lux/concurrency/frp.lux | 4 +-- stdlib/test/test/lux/concurrency/promise.lux | 2 +- 4 files changed, 48 insertions(+), 19 deletions(-) diff --git a/stdlib/source/lux/io.lux b/stdlib/source/lux/io.lux index 8aefdf0a5..d3e08169e 100644 --- a/stdlib/source/lux/io.lux +++ b/stdlib/source/lux/io.lux @@ -1,16 +1,15 @@ (;module: {#;doc "A method for abstracting I/O and effectful computations to make it safe while writing pure functional code."} lux - (lux (control ["F" functor] - ["A" applicative] - ["M" monad #+ do Monad]) - (data (coll [list])))) + (lux (control [functor #+ Functor] + [applicative #+ Applicative] + [monad #+ do Monad]) + (data ["e" error #+ Error] + (coll [list])))) -## [Types] (type: #export (IO a) {#;doc "A type that represents synchronous, effectful computations that may interact with the outside world."} (-> Void a)) -## [Syntax] (macro: #export (io tokens state) {#;doc (doc "Delays the evaluation of an expression, by wrapping it in an IO 'thunk'." "Great for wrapping effectful computations (which will not be performed until the IO is \"run\")." @@ -25,12 +24,11 @@ _ (#;Left "Wrong syntax for io"))) -## [Structures] -(struct: #export _ (F;Functor IO) +(struct: #export _ (Functor IO) (def: (map f ma) (io (f (ma (:! Void [])))))) -(struct: #export _ (A;Applicative IO) +(struct: #export _ (Applicative IO) (def: functor Functor) (def: (wrap x) @@ -45,8 +43,39 @@ (def: (join mma) (io ((mma (:! Void [])) (:! Void []))))) -## [Functions] (def: #export (run action) {#;doc "A way to execute IO computations and perform their side-effects."} (All [a] (-> (IO a) a)) (action (:! Void []))) + +## Process +(type: #export (Process a) + (IO (Error a))) + +(struct: #export _ (Functor Process) + (def: (map f ma) + (io (:: e;Functor map f (run ma))))) + +(struct: #export _ (Applicative Process) + (def: functor Functor) + + (def: (wrap x) + (io (:: e;Applicative wrap x))) + + (def: (apply ff fa) + (io (:: e;Applicative apply (run ff) (run fa))))) + +(struct: #export _ (Monad Process) + (def: applicative Applicative) + + (def: (join mma) + (case (run mma) + (#e;Success ma) + ma + + (#e;Error error) + (io (#e;Error error))))) + +(def: #export (fail error) + (All [a] (-> Text (Process a))) + (io (#e;Error error))) diff --git a/stdlib/test/test/lux/concurrency/actor.lux b/stdlib/test/test/lux/concurrency/actor.lux index c6c127fde..8abcae045 100644 --- a/stdlib/test/test/lux/concurrency/actor.lux +++ b/stdlib/test/test/lux/concurrency/actor.lux @@ -1,6 +1,6 @@ (;module: lux - (lux [io #- run] + (lux [io #+ IO io] (control ["M" monad #+ do Monad] ["ex" exception]) (data [number] @@ -34,26 +34,26 @@ (context: "Actors" ($_ seq (test "Can check if an actor is alive." - (io;run (do Monad + (io;run (do io;Monad [counter (new@Counter +0)] (wrap (&;alive? counter))))) (test "Can kill actors." - (io;run (do Monad + (io;run (do io;Monad [counter (new@Counter +0) killed? (&;kill counter)] (wrap (and killed? (not (&;alive? counter))))))) (test "Can poison actors." - (io;run (do Monad + (io;run (do io;Monad [counter (new@Counter +0) poisoned? (&;poison counter)] (wrap (and poisoned? (not (&;alive? counter))))))) (test "Cannot kill an already dead actor." - (io;run (do Monad + (io;run (do io;Monad [counter (new@Counter +0) first-time (&;kill counter) second-time (&;kill counter)] @@ -61,7 +61,7 @@ (not second-time)))))) (test "Cannot poison an already dead actor." - (io;run (do Monad + (io;run (do io;Monad [counter (new@Counter +0) first-time (&;kill counter) second-time (&;poison counter)] diff --git a/stdlib/test/test/lux/concurrency/frp.lux b/stdlib/test/test/lux/concurrency/frp.lux index 21a650882..3fb3d847a 100644 --- a/stdlib/test/test/lux/concurrency/frp.lux +++ b/stdlib/test/test/lux/concurrency/frp.lux @@ -1,6 +1,6 @@ (;module: lux - (lux [io #- run] + (lux [io #+ IO io] (control ["M" monad #+ do Monad]) (data [number] text/format) @@ -11,7 +11,7 @@ (def: (to-channel values) (-> (List Int) (&;Channel Int)) (let [_channel (&;channel Int)] - (io;run (do Monad + (io;run (do io;Monad [_ (M;map @ (function [value] (&;write value _channel)) values) _ (&;close _channel)] diff --git a/stdlib/test/test/lux/concurrency/promise.lux b/stdlib/test/test/lux/concurrency/promise.lux index 6ebc5ee5a..26193851a 100644 --- a/stdlib/test/test/lux/concurrency/promise.lux +++ b/stdlib/test/test/lux/concurrency/promise.lux @@ -1,6 +1,6 @@ (;module: lux - (lux [io #- run] + (lux [io #+ IO io] (control ["M" monad #+ do Monad] pipe) (data [number] -- cgit v1.2.3