@@ -6,13 +6,16 @@ import Data.Newtype (class Newtype)
66import Data.Traversable (traverse )
77import Effect (Effect )
88import 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 )
1111import Web.Promise.Internal as P
1212
13+ -- | A trivial box that adds a layer between promises to prevent automatic flattening.
14+ data Box a = Box a
15+
1316-- | A pure `Promise` that has not been executed yet. This type can be used
1417-- | with `do` syntax.
15- newtype LazyPromise a = LazyPromise (Effect (P.Promise a ))
18+ newtype LazyPromise a = LazyPromise (Effect (P.Promise ( Box a ) ))
1619
1720derive instance newtypeLazyPromise :: Newtype (LazyPromise a ) _
1821
@@ -23,17 +26,21 @@ instance applyLazyPromise :: Apply LazyPromise where
2326 apply = ap
2427
2528instance applicativeLazyPromise :: Applicative LazyPromise where
26- pure = LazyPromise <<< pure <<< P .resolve
29+ pure = LazyPromise <<< pure <<< P .resolve <<< Box
2730
2831instance bindLazyPromise :: Bind LazyPromise where
2932 bind (LazyPromise p) k = LazyPromise do
3033 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'
3235
3336instance monadLazyPromise :: Monad LazyPromise
3437
3538instance 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)
3744
3845catch :: forall a b . (Rejection -> LazyPromise b ) -> LazyPromise a -> LazyPromise b
3946catch k (LazyPromise p) = LazyPromise do
@@ -43,14 +50,21 @@ catch k (LazyPromise p) = LazyPromise do
4350finally :: forall a . LazyPromise Unit -> LazyPromise a -> LazyPromise a
4451finally (LazyPromise p1) (LazyPromise p2) = LazyPromise do
4552 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'
4758
4859all :: forall a . Array (LazyPromise a ) -> LazyPromise (Array a )
4960all as = LazyPromise do
5061 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)))
5266
5367race :: forall a . Array (LazyPromise a ) -> LazyPromise a
5468race as = LazyPromise do
5569 as' <- traverse (\(LazyPromise a) -> a) as
56- runEffectFn1 P .race as'
70+ runEffectFn1 P .race as'
0 commit comments