@@ -6,13 +6,16 @@ import Data.Newtype (class Newtype)
6
6
import Data.Traversable (traverse )
7
7
import Effect (Effect )
8
8
import Effect.Class (class MonadEffect )
9
- import Effect.Uncurried (mkEffectFn1 , runEffectFn1 , runEffectFn2 )
10
- import Web.Promise (Rejection )
9
+ import Effect.Uncurried (mkEffectFn1 , mkEffectFn2 , runEffectFn1 , runEffectFn2 )
10
+ import Web.Promise (Executor , Rejection )
11
11
import Web.Promise.Internal as P
12
12
13
+ -- | A trivial box that adds a layer between promises to prevent automatic flattening.
14
+ data Box a = Box a
15
+
13
16
-- | A pure `Promise` that has not been executed yet. This type can be used
14
17
-- | with `do` syntax.
15
- newtype LazyPromise a = LazyPromise (Effect (P.Promise a ))
18
+ newtype LazyPromise a = LazyPromise (Effect (P.Promise ( Box a ) ))
16
19
17
20
derive instance newtypeLazyPromise :: Newtype (LazyPromise a ) _
18
21
@@ -23,17 +26,21 @@ instance applyLazyPromise :: Apply LazyPromise where
23
26
apply = ap
24
27
25
28
instance applicativeLazyPromise :: Applicative LazyPromise where
26
- pure = LazyPromise <<< pure <<< P .resolve
29
+ pure = LazyPromise <<< pure <<< P .resolve <<< Box
27
30
28
31
instance bindLazyPromise :: Bind LazyPromise where
29
32
bind (LazyPromise p) k = LazyPromise do
30
33
p' <- p
31
- runEffectFn2 P .then_ (mkEffectFn1 \a -> let (LazyPromise b) = k a in b) p'
34
+ runEffectFn2 P .then_ (mkEffectFn1 \( Box a) -> let (LazyPromise b) = k a in b) p'
32
35
33
36
instance monadLazyPromise :: Monad LazyPromise
34
37
35
38
instance monadEffectLazyPromise :: MonadEffect LazyPromise where
36
- liftEffect = LazyPromise <<< map P .resolve
39
+ liftEffect = LazyPromise <<< map (P .resolve <<< Box )
40
+
41
+ new :: forall a . Executor a -> LazyPromise a
42
+ new k = LazyPromise $ runEffectFn1 P .new $ mkEffectFn2 \onResolve onReject ->
43
+ k (runEffectFn1 onResolve <<< Box ) (runEffectFn1 onReject)
37
44
38
45
catch :: forall a b . (Rejection -> LazyPromise b ) -> LazyPromise a -> LazyPromise b
39
46
catch k (LazyPromise p) = LazyPromise do
@@ -43,14 +50,21 @@ catch k (LazyPromise p) = LazyPromise do
43
50
finally :: forall a . LazyPromise Unit -> LazyPromise a -> LazyPromise a
44
51
finally (LazyPromise p1) (LazyPromise p2) = LazyPromise do
45
52
p2' <- p2
46
- runEffectFn2 P .finally p1 p2'
53
+ runEffectFn2 P .finally finalize p2'
54
+ where
55
+ finalize = do
56
+ p1' <- p1
57
+ runEffectFn2 P .then_ (mkEffectFn1 \(Box a) -> pure (P .resolve a)) p1'
47
58
48
59
all :: forall a . Array (LazyPromise a ) -> LazyPromise (Array a )
49
60
all as = LazyPromise do
50
61
as' <- traverse (\(LazyPromise a) -> a) as
51
- runEffectFn1 P .all as'
62
+ as'' <- runEffectFn1 P .all as'
63
+ runEffectFn2 P .then_ rebox as''
64
+ where
65
+ rebox = mkEffectFn1 \bs -> pure (P .resolve (Box (map (\(Box b) -> b) bs)))
52
66
53
67
race :: forall a . Array (LazyPromise a ) -> LazyPromise a
54
68
race as = LazyPromise do
55
69
as' <- traverse (\(LazyPromise a) -> a) as
56
- runEffectFn1 P .race as'
70
+ runEffectFn1 P .race as'
0 commit comments