aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEduardo Julian2017-11-16 01:45:40 -0400
committerEduardo Julian2017-11-16 01:45:40 -0400
commit4abfd5413b5a7aa540d7c06b387e3426ff5c532c (patch)
tree7f5ba092e7493ce5642e0dc4069913825ec97494
parent37b94ba49afb272c63ec66e42d56b8fba35cea9f (diff)
- Added "Process" type for IO operations that can fail.
-rw-r--r--stdlib/source/lux/io.lux49
-rw-r--r--stdlib/test/test/lux/concurrency/actor.lux12
-rw-r--r--stdlib/test/test/lux/concurrency/frp.lux4
-rw-r--r--stdlib/test/test/lux/concurrency/promise.lux2
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<IO>)
(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<Error> map f (run ma)))))
+
+(struct: #export _ (Applicative Process)
+ (def: functor Functor<Process>)
+
+ (def: (wrap x)
+ (io (:: e;Applicative<Error> wrap x)))
+
+ (def: (apply ff fa)
+ (io (:: e;Applicative<Error> apply (run ff) (run fa)))))
+
+(struct: #export _ (Monad Process)
+ (def: applicative Applicative<Process>)
+
+ (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>
+ (io;run (do io;Monad<IO>
[counter (new@Counter +0)]
(wrap (&;alive? counter)))))
(test "Can kill actors."
- (io;run (do Monad<IO>
+ (io;run (do io;Monad<IO>
[counter (new@Counter +0)
killed? (&;kill counter)]
(wrap (and killed?
(not (&;alive? counter)))))))
(test "Can poison actors."
- (io;run (do Monad<IO>
+ (io;run (do io;Monad<IO>
[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>
+ (io;run (do io;Monad<IO>
[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>
+ (io;run (do io;Monad<IO>
[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>
+ (io;run (do io;Monad<IO>
[_ (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]