(;module: lux (lux (data ["E" error]) (control ["F" functor] ["A" applicative] monad ["ex" exception #+ Exception]) (concurrency ["P" promise]) [macro] (macro ["s" syntax #+ syntax: Syntax]) )) (type: #export (Task a) (P;Promise (E;Error a))) (def: #export (fail error) (All [a] (-> Text (Task a))) (:: P;Applicative wrap (#E;Error error))) (def: #export (throw exception message) (All [a] (-> Exception Text (Task a))) (fail (exception message))) (def: #export (return value) (All [a] (-> a (Task a))) (:: P;Applicative wrap (#E;Success value))) (def: #export (try computation) (All [a] (-> (Task a) (Task (E;Error a)))) (:: P;Functor map (|>. #E;Success) computation)) (struct: #export _ (F;Functor Task) (def: (map f fa) (:: P;Functor map (function [fa'] (case fa' (#E;Error error) (#E;Error error) (#E;Success a) (#E;Success (f a)))) fa))) (struct: #export _ (A;Applicative Task) (def: functor Functor) (def: wrap return) (def: (apply ff fa) (do P;Monad [ff' ff fa' fa] (wrap (do E;Monad [f ff' a fa'] (wrap (f a))))))) (struct: #export _ (Monad Task) (def: applicative Applicative) (def: (join mma) (do P;Monad [mma' mma] (case mma' (#E;Error error) (wrap (#E;Error error)) (#E;Success ma) ma)))) (syntax: #export (task [type s;any]) {#;doc (doc "Makes an uninitialized Task (in this example, of Unit)." (task Unit))} (wrap (list (` (: (;;Task (~ type)) (P;promise' #;None)))))) (def: #export (from-promise promise) (All [a] (-> (P;Promise a) (Task a))) (:: P;Functor map (|>. #E;Success) promise))