From acad4646a0c0b6dc94e1988ee4b35e429ee5629b Mon Sep 17 00:00:00 2001 From: Thomas Honeyman Date: Wed, 10 Nov 2021 22:48:47 +0100 Subject: [PATCH 1/4] Add purs-tidy formatter --- .github/workflows/ci.yml | 9 +++++++-- .gitignore | 1 + .tidyrc.json | 10 ++++++++++ CHANGELOG.md | 1 + 4 files changed, 19 insertions(+), 2 deletions(-) create mode 100644 .tidyrc.json diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0b3ca67..43f9f20 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,6 +15,8 @@ jobs: - name: Set up PureScript toolchain uses: purescript-contrib/setup-purescript@main + with: + purs-tidy: "latest" - name: Cache PureScript dependencies uses: actions/cache@v2 @@ -25,9 +27,9 @@ jobs: output - name: Set up Node toolchain - uses: actions/setup-node@v1 + uses: actions/setup-node@v2 with: - node-version: "12.x" + node-version: "14.x" - name: Cache NPM dependencies uses: actions/cache@v2 @@ -49,3 +51,6 @@ jobs: - name: Run tests run: npm run test + + - name: Check formatting + run: purs-tidy check src test diff --git a/.gitignore b/.gitignore index 5a54e2f..6a45203 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ !.gitignore !.github !.editorconfig +!.tidyrc.json !.eslintrc.json output diff --git a/.tidyrc.json b/.tidyrc.json new file mode 100644 index 0000000..4f013c1 --- /dev/null +++ b/.tidyrc.json @@ -0,0 +1,10 @@ +{ + "importSort": "source", + "importWrap": "source", + "indent": 2, + "operatorsFile": null, + "ribbon": 1, + "typeArrowPlacement": "first", + "unicode": "never", + "width": null +} diff --git a/CHANGELOG.md b/CHANGELOG.md index e2aaec1..858ba9e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ New features: Bugfixes: Other improvements: +- Added `purs-tidy` formatter (#207 by @thomashoneyman) - Ensure all directly-imported packages are included in the `spago.dhall` file (#205 by @ptrfrncsmrph) ## [v6.0.0](https://github.com/purescript-contrib/purescript-aff/releases/tag/v6.0.0) - 2021-02-26 From f57949a9cc537cbbf5ba0e8cc13581a3400c5c62 Mon Sep 17 00:00:00 2001 From: Thomas Honeyman Date: Wed, 10 Nov 2021 22:48:48 +0100 Subject: [PATCH 2/4] Run purs-tidy --- src/Effect/Aff.purs | 238 ++++++++-------- src/Effect/Aff/Class.purs | 22 +- src/Effect/Aff/Compat.purs | 8 +- test/Test/Bench.purs | 60 ++-- test/Test/Main.purs | 569 +++++++++++++++++++------------------ 5 files changed, 454 insertions(+), 443 deletions(-) diff --git a/src/Effect/Aff.purs b/src/Effect/Aff.purs index 9163ca0..21ff748 100644 --- a/src/Effect/Aff.purs +++ b/src/Effect/Aff.purs @@ -61,232 +61,232 @@ import Unsafe.Coerce (unsafeCoerce) -- | computation may either error with an exception, or produce a result of -- | type `a`. `Aff` effects are assembled from primitive `Effect` effects using -- | `makeAff` or `liftEffect`. -foreign import data Aff ∷ Type → Type +foreign import data Aff :: Type -> Type type role Aff representational -instance functorAff ∷ Functor Aff where +instance functorAff :: Functor Aff where map = _map -instance applyAff ∷ Apply Aff where +instance applyAff :: Apply Aff where apply = ap -instance applicativeAff ∷ Applicative Aff where +instance applicativeAff :: Applicative Aff where pure = _pure -instance bindAff ∷ Bind Aff where +instance bindAff :: Bind Aff where bind = _bind -instance monadAff ∷ Monad Aff +instance monadAff :: Monad Aff -instance semigroupAff ∷ Semigroup a ⇒ Semigroup (Aff a) where +instance semigroupAff :: Semigroup a => Semigroup (Aff a) where append = lift2 append -instance monoidAff ∷ Monoid a ⇒ Monoid (Aff a) where +instance monoidAff :: Monoid a => Monoid (Aff a) where mempty = pure mempty -instance altAff ∷ Alt Aff where +instance altAff :: Alt Aff where alt a1 a2 = catchError a1 (const a2) -instance plusAff ∷ Plus Aff where +instance plusAff :: Plus Aff where empty = throwError (error "Always fails") -- | This instance is provided for compatibility. `Aff` is always stack-safe -- | within a given fiber. This instance will just result in unnecessary -- | bind overhead. -instance monadRecAff ∷ MonadRec Aff where +instance monadRecAff :: MonadRec Aff where tailRecM k = go where go a = do - res ← k a + res <- k a case res of - Done r → pure r - Loop b → go b + Done r -> pure r + Loop b -> go b -instance monadThrowAff ∷ MonadThrow Error Aff where +instance monadThrowAff :: MonadThrow Error Aff where throwError = _throwError -instance monadErrorAff ∷ MonadError Error Aff where +instance monadErrorAff :: MonadError Error Aff where catchError = _catchError -instance monadEffectAff ∷ MonadEffect Aff where +instance monadEffectAff :: MonadEffect Aff where liftEffect = _liftEffect -instance lazyAff ∷ Lazy (Aff a) where +instance lazyAff :: Lazy (Aff a) where defer f = pure unit >>= f -- | Applicative for running parallel effects. Any `Aff` can be coerced to a -- | `ParAff` and back using the `Parallel` class. -foreign import data ParAff ∷ Type → Type +foreign import data ParAff :: Type -> Type type role ParAff representational -instance functorParAff ∷ Functor ParAff where +instance functorParAff :: Functor ParAff where map = _parAffMap -- | Runs effects in parallel, combining their results. -instance applyParAff ∷ Apply ParAff where +instance applyParAff :: Apply ParAff where apply = _parAffApply -instance applicativeParAff ∷ Applicative ParAff where +instance applicativeParAff :: Applicative ParAff where pure = parallel <<< pure -instance semigroupParAff ∷ Semigroup a ⇒ Semigroup (ParAff a) where +instance semigroupParAff :: Semigroup a => Semigroup (ParAff a) where append = lift2 append -instance monoidParAff ∷ Monoid a ⇒ Monoid (ParAff a) where +instance monoidParAff :: Monoid a => Monoid (ParAff a) where mempty = pure mempty -- | Races effects in parallel. Returns the first successful result or the -- | first error if all fail with an exception. Losing branches will be -- | cancelled. -instance altParAff ∷ Alt ParAff where +instance altParAff :: Alt ParAff where alt = _parAffAlt -instance plusParAff ∷ Plus ParAff where +instance plusParAff :: Plus ParAff where empty = parallel empty -instance alternativeParAff ∷ Alternative ParAff +instance alternativeParAff :: Alternative ParAff -instance parallelAff ∷ Parallel ParAff Aff where - parallel = (unsafeCoerce ∷ ∀ a. Aff a → ParAff a) +instance parallelAff :: Parallel ParAff Aff where + parallel = (unsafeCoerce :: forall a. Aff a -> ParAff a) sequential = _sequential type OnComplete a = - { rethrow ∷ Boolean - , handler ∷ (Either Error a → Effect Unit) → Effect Unit + { rethrow :: Boolean + , handler :: (Either Error a -> Effect Unit) -> Effect Unit } -- | Represents a forked computation by way of `forkAff`. `Fiber`s are -- | memoized, so their results are only computed once. newtype Fiber a = Fiber - { run ∷ Effect Unit - , kill ∷ Fn.Fn2 Error (Either Error Unit → Effect Unit) (Effect (Effect Unit)) - , join ∷ (Either Error a → Effect Unit) → Effect (Effect Unit) - , onComplete ∷ OnComplete a → Effect (Effect Unit) - , isSuspended ∷ Effect Boolean + { run :: Effect Unit + , kill :: Fn.Fn2 Error (Either Error Unit -> Effect Unit) (Effect (Effect Unit)) + , join :: (Either Error a -> Effect Unit) -> Effect (Effect Unit) + , onComplete :: OnComplete a -> Effect (Effect Unit) + , isSuspended :: Effect Boolean } -instance functorFiber ∷ Functor Fiber where +instance functorFiber :: Functor Fiber where map f t = unsafePerformEffect (makeFiber (f <$> joinFiber t)) -instance applyFiber ∷ Apply Fiber where +instance applyFiber :: Apply Fiber where apply t1 t2 = unsafePerformEffect (makeFiber (joinFiber t1 <*> joinFiber t2)) -instance applicativeFiber ∷ Applicative Fiber where +instance applicativeFiber :: Applicative Fiber where pure a = unsafePerformEffect (makeFiber (pure a)) -- | Invokes pending cancelers in a fiber and runs cleanup effects. Blocks -- | until the fiber has fully exited. -killFiber ∷ ∀ a. Error → Fiber a → Aff Unit -killFiber e (Fiber t) = liftEffect t.isSuspended >>= if _ - then liftEffect $ void $ Fn.runFn2 t.kill e (const (pure unit)) - else makeAff \k → effectCanceler <$> Fn.runFn2 t.kill e k +killFiber :: forall a. Error -> Fiber a -> Aff Unit +killFiber e (Fiber t) = liftEffect t.isSuspended >>= + if _ then liftEffect $ void $ Fn.runFn2 t.kill e (const (pure unit)) + else makeAff \k -> effectCanceler <$> Fn.runFn2 t.kill e k -- | Blocks until the fiber completes, yielding the result. If the fiber -- | throws an exception, it is rethrown in the current fiber. -joinFiber ∷ Fiber ~> Aff -joinFiber (Fiber t) = makeAff \k → effectCanceler <$> t.join k +joinFiber :: Fiber ~> Aff +joinFiber (Fiber t) = makeAff \k -> effectCanceler <$> t.join k -- | A cancellation effect for actions run via `makeAff`. If a `Fiber` is -- | killed, and an async action is pending, the canceler will be called to -- | clean it up. -newtype Canceler = Canceler (Error → Aff Unit) +newtype Canceler = Canceler (Error -> Aff Unit) -derive instance newtypeCanceler ∷ Newtype Canceler _ +derive instance newtypeCanceler :: Newtype Canceler _ -instance semigroupCanceler ∷ Semigroup Canceler where +instance semigroupCanceler :: Semigroup Canceler where append (Canceler c1) (Canceler c2) = - Canceler \err → parSequence_ [ c1 err, c2 err ] + Canceler \err -> parSequence_ [ c1 err, c2 err ] -- | A no-op `Canceler` can be constructed with `mempty`. -instance monoidCanceler ∷ Monoid Canceler where +instance monoidCanceler :: Monoid Canceler where mempty = nonCanceler -- | A canceler which does not cancel anything. -nonCanceler ∷ Canceler +nonCanceler :: Canceler nonCanceler = Canceler (const (pure unit)) -- | A canceler from an Effect action. -effectCanceler ∷ Effect Unit → Canceler +effectCanceler :: Effect Unit -> Canceler effectCanceler = Canceler <<< const <<< liftEffect -- | A canceler from a Fiber. -fiberCanceler ∷ ∀ a. Fiber a → Canceler +fiberCanceler :: forall a. Fiber a -> Canceler fiberCanceler = Canceler <<< flip killFiber -- | Forks an `Aff` from an `Effect` context, returning the `Fiber`. -launchAff ∷ ∀ a. Aff a → Effect (Fiber a) +launchAff :: forall a. Aff a -> Effect (Fiber a) launchAff aff = do - fiber ← makeFiber aff - case fiber of Fiber f → f.run + fiber <- makeFiber aff + case fiber of Fiber f -> f.run pure fiber -- | Forks an `Aff` from an `Effect` context, discarding the `Fiber`. -launchAff_ ∷ ∀ a. Aff a → Effect Unit +launchAff_ :: forall a. Aff a -> Effect Unit launchAff_ = void <<< launchAff -- | Suspends an `Aff` from an `Effect` context, returning the `Fiber`. -launchSuspendedAff ∷ ∀ a. Aff a → Effect (Fiber a) +launchSuspendedAff :: forall a. Aff a -> Effect (Fiber a) launchSuspendedAff = makeFiber -- | Forks an `Aff` from an `Effect` context and also takes a callback to run when -- | it completes. Returns the pending `Fiber`. -runAff ∷ ∀ a. (Either Error a → Effect Unit) → Aff a → Effect (Fiber Unit) +runAff :: forall a. (Either Error a -> Effect Unit) -> Aff a -> Effect (Fiber Unit) runAff k aff = launchAff $ liftEffect <<< k =<< try aff -- | Forks an `Aff` from an `Effect` context and also takes a callback to run when -- | it completes, discarding the `Fiber`. -runAff_ ∷ ∀ a. (Either Error a → Effect Unit) → Aff a → Effect Unit +runAff_ :: forall a. (Either Error a -> Effect Unit) -> Aff a -> Effect Unit runAff_ k aff = void $ runAff k aff -- | Suspends an `Aff` from an `Effect` context and also takes a callback to run -- | when it completes. Returns the suspended `Fiber`. -runSuspendedAff ∷ ∀ a. (Either Error a → Effect Unit) → Aff a → Effect (Fiber Unit) +runSuspendedAff :: forall a. (Either Error a -> Effect Unit) -> Aff a -> Effect (Fiber Unit) runSuspendedAff k aff = launchSuspendedAff $ liftEffect <<< k =<< try aff -- | Forks an `Aff` from within a parent `Aff` context, returning the `Fiber`. -forkAff ∷ ∀ a. Aff a → Aff (Fiber a) +forkAff :: forall a. Aff a -> Aff (Fiber a) forkAff = _fork true -- | Suspends an `Aff` from within a parent `Aff` context, returning the `Fiber`. -- | A suspended `Aff` is not executed until a consumer observes the result -- | with `joinFiber`. -suspendAff ∷ ∀ a. Aff a → Aff (Fiber a) +suspendAff :: forall a. Aff a -> Aff (Fiber a) suspendAff = _fork false -- | Pauses the running fiber. -delay ∷ Milliseconds → Aff Unit +delay :: Milliseconds -> Aff Unit delay (Milliseconds n) = Fn.runFn2 _delay Right n -- | An async computation which does not resolve. -never ∷ ∀ a. Aff a -never = makeAff \_ → pure mempty +never :: forall a. Aff a +never = makeAff \_ -> pure mempty -- | A monomorphic version of `try`. Catches thrown errors and lifts them -- | into an `Either`. -attempt ∷ ∀ a. Aff a → Aff (Either Error a) +attempt :: forall a. Aff a -> Aff (Either Error a) attempt = try -- | Ignores any errors. -apathize ∷ ∀ a. Aff a → Aff Unit +apathize :: forall a. Aff a -> Aff Unit apathize = attempt >>> map (const unit) -- | Runs the first effect after the second, regardless of whether it completed -- | successfully or the fiber was cancelled. -finally ∷ ∀ a. Aff Unit → Aff a → Aff a +finally :: forall a. Aff Unit -> Aff a -> Aff a finally fin a = bracket (pure unit) (const fin) (const a) -- | Runs an effect such that it cannot be killed. -invincible ∷ ∀ a. Aff a → Aff a +invincible :: forall a. Aff a -> Aff a invincible a = bracket a (const (pure unit)) pure -- | Attaches a custom `Canceler` to an action. If the computation is canceled, -- | then the custom `Canceler` will be run afterwards. -cancelWith ∷ ∀ a. Aff a → Canceler → Aff a +cancelWith :: forall a. Aff a -> Canceler -> Aff a cancelWith aff (Canceler cancel) = generalBracket (pure unit) - { killed: \e _ → cancel e + { killed: \e _ -> cancel e , failed: const pure , completed: const pure } @@ -297,7 +297,7 @@ cancelWith aff (Canceler cancel) = -- | use of the resource. Disposal is always run last, regardless. Neither -- | acquisition nor disposal may be cancelled and are guaranteed to run until -- | they complete. -bracket ∷ ∀ a b. Aff a → (a → Aff Unit) → (a → Aff b) → Aff b +bracket :: forall a b. Aff a -> (a -> Aff Unit) -> (a -> Aff b) -> Aff b bracket acquire completed = generalBracket acquire { killed: const completed @@ -306,82 +306,82 @@ bracket acquire completed = } type Supervised a = - { fiber ∷ Fiber a - , supervisor ∷ Supervisor + { fiber :: Fiber a + , supervisor :: Supervisor } -- | Creates a new supervision context for some `Aff`, guaranteeing fiber -- | cleanup when the parent completes. Any pending fibers forked within -- | the context will be killed and have their cancelers run. -supervise ∷ ∀ a. Aff a → Aff a +supervise :: forall a. Aff a -> Aff a supervise aff = generalBracket (liftEffect acquire) - { killed: \err sup → parSequence_ [ killFiber err sup.fiber, killAll err sup ] + { killed: \err sup -> parSequence_ [ killFiber err sup.fiber, killAll err sup ] , failed: const (killAll killError) , completed: const (killAll killError) } (joinFiber <<< _.fiber) where - killError ∷ Error + killError :: Error killError = error "[Aff] Child fiber outlived parent" - killAll ∷ Error → Supervised a → Aff Unit - killAll err sup = makeAff \k → + killAll :: Error -> Supervised a -> Aff Unit + killAll err sup = makeAff \k -> Fn.runFn3 _killAll err sup.supervisor (k (pure unit)) - acquire ∷ Effect (Supervised a) + acquire :: Effect (Supervised a) acquire = do - sup ← Fn.runFn2 _makeSupervisedFiber ffiUtil aff - case sup.fiber of Fiber f → f.run + sup <- Fn.runFn2 _makeSupervisedFiber ffiUtil aff + case sup.fiber of Fiber f -> f.run pure sup -foreign import data Supervisor ∷ Type -foreign import _pure ∷ ∀ a. a → Aff a -foreign import _throwError ∷ ∀ a. Error → Aff a -foreign import _catchError ∷ ∀ a. Aff a → (Error → Aff a) → Aff a -foreign import _fork ∷ ∀ a. Boolean → Aff a → Aff (Fiber a) -foreign import _map ∷ ∀ a b. (a → b) → Aff a → Aff b -foreign import _bind ∷ ∀ a b. Aff a → (a → Aff b) → Aff b -foreign import _delay ∷ ∀ a. Fn.Fn2 (Unit → Either a Unit) Number (Aff Unit) -foreign import _liftEffect ∷ ∀ a. Effect a → Aff a -foreign import _parAffMap ∷ ∀ a b. (a → b) → ParAff a → ParAff b -foreign import _parAffApply ∷ ∀ a b. ParAff (a → b) → ParAff a → ParAff b -foreign import _parAffAlt ∷ ∀ a. ParAff a → ParAff a → ParAff a -foreign import _makeFiber ∷ ∀ a. Fn.Fn2 FFIUtil (Aff a) (Effect (Fiber a)) -foreign import _makeSupervisedFiber ∷ ∀ a. Fn.Fn2 FFIUtil (Aff a) (Effect (Supervised a)) -foreign import _killAll ∷ Fn.Fn3 Error Supervisor (Effect Unit) (Effect Canceler) -foreign import _sequential ∷ ParAff ~> Aff +foreign import data Supervisor :: Type +foreign import _pure :: forall a. a -> Aff a +foreign import _throwError :: forall a. Error -> Aff a +foreign import _catchError :: forall a. Aff a -> (Error -> Aff a) -> Aff a +foreign import _fork :: forall a. Boolean -> Aff a -> Aff (Fiber a) +foreign import _map :: forall a b. (a -> b) -> Aff a -> Aff b +foreign import _bind :: forall a b. Aff a -> (a -> Aff b) -> Aff b +foreign import _delay :: forall a. Fn.Fn2 (Unit -> Either a Unit) Number (Aff Unit) +foreign import _liftEffect :: forall a. Effect a -> Aff a +foreign import _parAffMap :: forall a b. (a -> b) -> ParAff a -> ParAff b +foreign import _parAffApply :: forall a b. ParAff (a -> b) -> ParAff a -> ParAff b +foreign import _parAffAlt :: forall a. ParAff a -> ParAff a -> ParAff a +foreign import _makeFiber :: forall a. Fn.Fn2 FFIUtil (Aff a) (Effect (Fiber a)) +foreign import _makeSupervisedFiber :: forall a. Fn.Fn2 FFIUtil (Aff a) (Effect (Supervised a)) +foreign import _killAll :: Fn.Fn3 Error Supervisor (Effect Unit) (Effect Canceler) +foreign import _sequential :: ParAff ~> Aff type BracketConditions a b = - { killed ∷ Error → a → Aff Unit - , failed ∷ Error → a → Aff Unit - , completed ∷ b → a → Aff Unit + { killed :: Error -> a -> Aff Unit + , failed :: Error -> a -> Aff Unit + , completed :: b -> a -> Aff Unit } -- | A general purpose bracket which lets you observe the status of the -- | bracketed action. The bracketed action may have been killed with an -- | exception, thrown an exception, or completed successfully. -foreign import generalBracket ∷ ∀ a b. Aff a → BracketConditions a b → (a → Aff b) → Aff b +foreign import generalBracket :: forall a b. Aff a -> BracketConditions a b -> (a -> Aff b) -> Aff b -- | Constructs an `Aff` from low-level `Effect` effects using a callback. A -- | `Canceler` effect should be returned to cancel the pending action. The -- | supplied callback may be invoked only once. Subsequent invocation are -- | ignored. -foreign import makeAff ∷ ∀ a. ((Either Error a → Effect Unit) → Effect Canceler) → Aff a +foreign import makeAff :: forall a. ((Either Error a -> Effect Unit) -> Effect Canceler) -> Aff a -makeFiber ∷ ∀ a. Aff a → Effect (Fiber a) +makeFiber :: forall a. Aff a -> Effect (Fiber a) makeFiber aff = Fn.runFn2 _makeFiber ffiUtil aff newtype FFIUtil = FFIUtil - { isLeft ∷ ∀ a b. Either a b → Boolean - , fromLeft ∷ ∀ a b. Either a b → a - , fromRight ∷ ∀ a b. Either a b → b - , left ∷ ∀ a b. a → Either a b - , right ∷ ∀ a b. b → Either a b + { isLeft :: forall a b. Either a b -> Boolean + , fromLeft :: forall a b. Either a b -> a + , fromRight :: forall a b. Either a b -> b + , left :: forall a b. a -> Either a b + , right :: forall a b. b -> Either a b } -ffiUtil ∷ FFIUtil +ffiUtil :: FFIUtil ffiUtil = FFIUtil { isLeft , fromLeft: unsafeFromLeft @@ -390,17 +390,17 @@ ffiUtil = FFIUtil , right: Right } where - isLeft ∷ ∀ a b. Either a b → Boolean + isLeft :: forall a b. Either a b -> Boolean isLeft = case _ of Left _ -> true - Right _ → false + Right _ -> false - unsafeFromLeft ∷ ∀ a b. Either a b → a + unsafeFromLeft :: forall a b. Either a b -> a unsafeFromLeft = case _ of - Left a → a - Right _ → unsafeCrashWith "unsafeFromLeft: Right" + Left a -> a + Right _ -> unsafeCrashWith "unsafeFromLeft: Right" - unsafeFromRight ∷ ∀ a b. Either a b → b + unsafeFromRight :: forall a b. Either a b -> b unsafeFromRight = case _ of - Right a → a - Left _ → unsafeCrashWith "unsafeFromRight: Left" + Right a -> a + Left _ -> unsafeCrashWith "unsafeFromRight: Left" diff --git a/src/Effect/Aff/Class.purs b/src/Effect/Aff/Class.purs index 2e3ef5f..7955174 100644 --- a/src/Effect/Aff/Class.purs +++ b/src/Effect/Aff/Class.purs @@ -13,32 +13,32 @@ import Control.Monad.Writer.Trans (WriterT) import Effect.Aff (Aff) import Effect.Class (class MonadEffect) -class MonadEffect m ⇐ MonadAff m where - liftAff ∷ Aff ~> m +class MonadEffect m <= MonadAff m where + liftAff :: Aff ~> m -instance monadAffAff ∷ MonadAff Aff where +instance monadAffAff :: MonadAff Aff where liftAff = identity -instance monadAffContT ∷ MonadAff m ⇒ MonadAff (ContT r m) where +instance monadAffContT :: MonadAff m => MonadAff (ContT r m) where liftAff = lift <<< liftAff -instance monadAffExceptT ∷ MonadAff m ⇒ MonadAff (ExceptT e m) where +instance monadAffExceptT :: MonadAff m => MonadAff (ExceptT e m) where liftAff = lift <<< liftAff -instance monadAffListT ∷ MonadAff m ⇒ MonadAff (ListT m) where +instance monadAffListT :: MonadAff m => MonadAff (ListT m) where liftAff = lift <<< liftAff -instance monadAffMaybe ∷ MonadAff m ⇒ MonadAff (MaybeT m) where +instance monadAffMaybe :: MonadAff m => MonadAff (MaybeT m) where liftAff = lift <<< liftAff -instance monadAffReader ∷ MonadAff m ⇒ MonadAff (ReaderT r m) where +instance monadAffReader :: MonadAff m => MonadAff (ReaderT r m) where liftAff = lift <<< liftAff -instance monadAffRWS ∷ (MonadAff m, Monoid w) ⇒ MonadAff (RWST r w s m) where +instance monadAffRWS :: (MonadAff m, Monoid w) => MonadAff (RWST r w s m) where liftAff = lift <<< liftAff -instance monadAffState ∷ MonadAff m ⇒ MonadAff (StateT s m) where +instance monadAffState :: MonadAff m => MonadAff (StateT s m) where liftAff = lift <<< liftAff -instance monadAffWriter ∷ (MonadAff m, Monoid w) ⇒ MonadAff (WriterT w m) where +instance monadAffWriter :: (MonadAff m, Monoid w) => MonadAff (WriterT w m) where liftAff = lift <<< liftAff diff --git a/src/Effect/Aff/Compat.purs b/src/Effect/Aff/Compat.purs index 541d1ef..13fe757 100644 --- a/src/Effect/Aff/Compat.purs +++ b/src/Effect/Aff/Compat.purs @@ -45,9 +45,9 @@ newtype EffectFnCanceler = EffectFnCanceler (EffectFn3 Error (EffectFnCb Error) -- | myAff :: Aff String -- | myAff = fromEffectFnAff _myAff -- | ```` -fromEffectFnAff ∷ EffectFnAff ~> Aff -fromEffectFnAff (EffectFnAff eff) = makeAff \k → do - EffectFnCanceler canceler ← runEffectFn2 eff (mkEffectFn1 (k <<< Left)) (mkEffectFn1 (k <<< Right)) - pure $ Canceler \e → makeAff \k2 → do +fromEffectFnAff :: EffectFnAff ~> Aff +fromEffectFnAff (EffectFnAff eff) = makeAff \k -> do + EffectFnCanceler canceler <- runEffectFn2 eff (mkEffectFn1 (k <<< Left)) (mkEffectFn1 (k <<< Right)) + pure $ Canceler \e -> makeAff \k2 -> do runEffectFn3 canceler e (mkEffectFn1 (k2 <<< Left)) (mkEffectFn1 (k2 <<< Right)) pure nonCanceler diff --git a/test/Test/Bench.purs b/test/Test/Bench.purs index 1b8862e..b68f28a 100644 --- a/test/Test/Bench.purs +++ b/test/Test/Bench.purs @@ -8,56 +8,58 @@ import Effect.Aff as Aff import Effect.Unsafe (unsafePerformEffect) import Effect.Console as Console -loop1 ∷ Int → Aff.Aff Int +loop1 :: Int -> Aff.Aff Int loop1 = tailRecM go where go n - | n <= 0 = pure $ Done n + | n <= 0 = pure $ Done n | otherwise = do - _ ← do - _ ← do - _ ← pure n - _ ← pure n - _ ← pure n + _ <- do + _ <- do + _ <- pure n + _ <- pure n + _ <- pure n pure n - _ ← pure n - _ ← pure n - _ ← pure n + _ <- pure n + _ <- pure n + _ <- pure n pure n pure $ Loop (n - 1) -loop2 ∷ Int → Aff.Aff Int +loop2 :: Int -> Aff.Aff Int loop2 = go where go n - | n <= 0 = pure n + | n <= 0 = pure n | otherwise = do - _ ← do - _ ← do - _ ← pure n - _ ← pure n - _ ← pure n + _ <- do + _ <- do + _ <- pure n + _ <- pure n + _ <- pure n pure n - _ ← pure n - _ ← pure n - _ ← pure n + _ <- pure n + _ <- pure n + _ <- pure n pure n loop2 (n - 1) -fib1 ∷ Int → Aff.Aff Int -fib1 n = if n <= 1 then pure n else do - a ← fib1 (n - 1) - b ← fib1 (n - 2) - pure (a + b) +fib1 :: Int -> Aff.Aff Int +fib1 n = + if n <= 1 then pure n + else do + a <- fib1 (n - 1) + b <- fib1 (n - 2) + pure (a + b) -main ∷ Effect Unit +main :: Effect Unit main = do Console.log "\nAff tailRecM:" - bench \_ → unsafePerformEffect $ void $ Aff.launchAff $ loop1 10000 + bench \_ -> unsafePerformEffect $ void $ Aff.launchAff $ loop1 10000 Console.log "\nAff loop:" - bench \_ → unsafePerformEffect $ void $ Aff.launchAff $ loop2 10000 + bench \_ -> unsafePerformEffect $ void $ Aff.launchAff $ loop2 10000 Console.log "\nAff fib:" - bench \_ → unsafePerformEffect $ void $ Aff.launchAff $ fib1 20 + bench \_ -> unsafePerformEffect $ void $ Aff.launchAff $ fib1 20 diff --git a/test/Test/Main.purs b/test/Test/Main.purs index 440e7a4..32dc476 100644 --- a/test/Test/Main.purs +++ b/test/Test/Main.purs @@ -24,199 +24,199 @@ import Effect.Ref as Ref import Effect.Unsafe (unsafePerformEffect) import Test.Assert (assert') -newRef ∷ ∀ m a. MonadEffect m ⇒ a → m (Ref a) +newRef :: forall m a. MonadEffect m => a -> m (Ref a) newRef = liftEffect <<< Ref.new -readRef ∷ ∀ m a. MonadEffect m ⇒ Ref a → m a +readRef :: forall m a. MonadEffect m => Ref a -> m a readRef = liftEffect <<< Ref.read -writeRef ∷ ∀ m a. MonadEffect m ⇒ Ref a → a → m Unit +writeRef :: forall m a. MonadEffect m => Ref a -> a -> m Unit writeRef r = liftEffect <<< flip Ref.write r -modifyRef ∷ ∀ m a. MonadEffect m ⇒ Ref a → (a → a) → m a +modifyRef :: forall m a. MonadEffect m => Ref a -> (a -> a) -> m a modifyRef r = liftEffect <<< flip Ref.modify r -assertEff ∷ String → Either Error Boolean → Effect Unit +assertEff :: String -> Either Error Boolean -> Effect Unit assertEff s = case _ of - Left err → do + Left err -> do Console.log ("[Error] " <> s) throwException err - Right r → do + Right r -> do assert' ("Assertion failure " <> s) r Console.log ("[OK] " <> s) -runAssert ∷ String → Aff Boolean → Effect Unit +runAssert :: String -> Aff Boolean -> Effect Unit runAssert s = runAff_ (assertEff s) -runAssertEq ∷ ∀ a. Eq a ⇒ String → a → Aff a → Effect Unit +runAssertEq :: forall a. Eq a => String -> a -> Aff a -> Effect Unit runAssertEq s a = runAff_ (assertEff s <<< map (eq a)) -assertEq ∷ ∀ a. Eq a ⇒ String → a → Aff a → Aff Unit +assertEq :: forall a. Eq a => String -> a -> Aff a -> Aff Unit assertEq s a aff = liftEffect <<< assertEff s <<< map (eq a) =<< try aff -assert ∷ String → Aff Boolean → Aff Unit +assert :: String -> Aff Boolean -> Aff Unit assert s aff = liftEffect <<< assertEff s =<< try aff -withTimeout ∷ ∀ a. Milliseconds → Aff a → Aff a +withTimeout :: forall a. Milliseconds -> Aff a -> Aff a withTimeout ms aff = either throwError pure =<< sequential do parallel (try aff) <|> parallel (delay ms $> Left (error "Timed out")) -test_pure ∷ Effect Unit +test_pure :: Effect Unit test_pure = runAssertEq "pure" 42 (pure 42) -test_bind ∷ Effect Unit +test_bind :: Effect Unit test_bind = runAssertEq "bind" 44 do - n1 ← pure 42 - n2 ← pure (n1 + 1) - n3 ← pure (n2 + 1) + n1 <- pure 42 + n2 <- pure (n1 + 1) + n3 <- pure (n2 + 1) pure n3 -test_try ∷ Effect Unit +test_try :: Effect Unit test_try = runAssert "try" do - n ← try (pure 42) + n <- try (pure 42) case n of - Right 42 → pure true - _ → pure false + Right 42 -> pure true + _ -> pure false -test_throw ∷ Effect Unit +test_throw :: Effect Unit test_throw = runAssert "try/throw" do - n ← try (throwError (error "Nope.")) + n <- try (throwError (error "Nope.")) pure (isLeft n) -test_liftEffect ∷ Effect Unit +test_liftEffect :: Effect Unit test_liftEffect = runAssertEq "liftEffect" 42 do - ref ← newRef 0 + ref <- newRef 0 liftEffect do writeRef ref 42 readRef ref -test_delay ∷ Aff Unit +test_delay :: Aff Unit test_delay = assert "delay" do delay (Milliseconds 1000.0) pure true -test_fork ∷ Aff Unit +test_fork :: Aff Unit test_fork = assert "fork" do - ref ← newRef "" - _ ← forkAff do + ref <- newRef "" + _ <- forkAff do delay (Milliseconds 10.0) modifyRef ref (_ <> "child") - _ ← modifyRef ref (_ <> "go") + _ <- modifyRef ref (_ <> "go") delay (Milliseconds 20.0) - _ ← modifyRef ref (_ <> "parent") + _ <- modifyRef ref (_ <> "parent") eq "gochildparent" <$> readRef ref -test_join ∷ Aff Unit +test_join :: Aff Unit test_join = assert "join" do - ref ← newRef "" - fiber ← forkAff do + ref <- newRef "" + fiber <- forkAff do delay (Milliseconds 10.0) - _ ← modifyRef ref (_ <> "child") + _ <- modifyRef ref (_ <> "child") readRef ref - _ ← modifyRef ref (_ <> "parent") + _ <- modifyRef ref (_ <> "parent") eq "parentchild" <$> joinFiber fiber -test_join_throw ∷ Aff Unit +test_join_throw :: Aff Unit test_join_throw = assert "join/throw" do - fiber ← forkAff do + fiber <- forkAff do delay (Milliseconds 10.0) throwError (error "Nope.") isLeft <$> try (joinFiber fiber) -test_join_throw_sync ∷ Aff Unit +test_join_throw_sync :: Aff Unit test_join_throw_sync = assert "join/throw/sync" do - fiber ← forkAff (throwError (error "Nope.")) + fiber <- forkAff (throwError (error "Nope.")) isLeft <$> try (joinFiber fiber) -test_multi_join ∷ Aff Unit +test_multi_join :: Aff Unit test_multi_join = assert "join/multi" do - ref ← newRef 1 - f1 ← forkAff do + ref <- newRef 1 + f1 <- forkAff do delay (Milliseconds 10.0) - _ ← modifyRef ref (_ + 1) + _ <- modifyRef ref (_ + 1) pure 10 - f2 ← forkAff do + f2 <- forkAff do delay (Milliseconds 20.0) - _ ← modifyRef ref (_ + 1) + _ <- modifyRef ref (_ + 1) pure 20 - n1 ← traverse joinFiber + n1 <- traverse joinFiber [ f1 , f1 , f1 , f2 ] - n2 ← readRef ref + n2 <- readRef ref pure (sum n1 == 50 && n2 == 3) -test_suspend ∷ Aff Unit +test_suspend :: Aff Unit test_suspend = assert "suspend" do - ref ← newRef "" - fiber ← suspendAff do + ref <- newRef "" + fiber <- suspendAff do delay (Milliseconds 10.0) modifyRef ref (_ <> "child") - _ ← modifyRef ref (_ <> "go") + _ <- modifyRef ref (_ <> "go") delay (Milliseconds 20.0) - _ ← modifyRef ref (_ <> "parent") - _ ← joinFiber fiber + _ <- modifyRef ref (_ <> "parent") + _ <- joinFiber fiber eq "goparentchild" <$> readRef ref -test_makeAff ∷ Aff Unit +test_makeAff :: Aff Unit test_makeAff = assert "makeAff" do - ref1 ← newRef Nothing - ref2 ← newRef 0 - fiber ← forkAff do - n ← makeAff \cb → do + ref1 <- newRef Nothing + ref2 <- newRef 0 + fiber <- forkAff do + n <- makeAff \cb -> do writeRef ref1 (Just cb) pure mempty writeRef ref2 n delay (Milliseconds 5.0) - cb ← readRef ref1 + cb <- readRef ref1 case cb of - Just k → do + Just k -> do liftEffect $ k (Right 42) - _ ← joinFiber fiber + _ <- joinFiber fiber eq 42 <$> readRef ref2 - Nothing → pure false + Nothing -> pure false -test_bracket ∷ Aff Unit +test_bracket :: Aff Unit test_bracket = assert "bracket" do - ref ← newRef [] + ref <- newRef [] let action s = do delay (Milliseconds 10.0) - _ ← modifyRef ref (_ <> [ s ]) + _ <- modifyRef ref (_ <> [ s ]) pure s - fiber ← forkAff do + fiber <- forkAff do delay (Milliseconds 40.0) readRef ref - _ ← bracket + _ <- bracket (action "foo") - (\s → void $ action (s <> "/release")) - (\s → action (s <> "/run")) + (\s -> void $ action (s <> "/release")) + (\s -> action (s <> "/run")) joinFiber fiber <#> eq [ "foo" , "foo/run" , "foo/release" ] -test_bracket_nested ∷ Aff Unit +test_bracket_nested :: Aff Unit test_bracket_nested = assert "bracket/nested" do - ref ← newRef [] + ref <- newRef [] let action s = do delay (Milliseconds 10.0) - _ ← modifyRef ref (_ <> [ s ]) + _ <- modifyRef ref (_ <> [ s ]) pure s bracketAction s = bracket (action (s <> "/bar")) - (\s' → void $ action (s' <> "/release")) - (\s' → action (s' <> "/run")) - _ ← bracket + (\s' -> void $ action (s' <> "/release")) + (\s' -> action (s' <> "/run")) + _ <- bracket (bracketAction "foo") - (\s → void $ bracketAction (s <> "/release")) - (\s → bracketAction (s <> "/run")) + (\s -> void $ bracketAction (s <> "/release")) + (\s -> bracketAction (s <> "/run")) readRef ref <#> eq [ "foo/bar" , "foo/bar/run" @@ -229,112 +229,112 @@ test_bracket_nested = assert "bracket/nested" do , "foo/bar/run/release/bar/release" ] -test_general_bracket ∷ Aff Unit +test_general_bracket :: Aff Unit test_general_bracket = assert "bracket/general" do - ref ← newRef "" + ref <- newRef "" let action s = do delay (Milliseconds 10.0) - _ ← modifyRef ref (_ <> s) + _ <- modifyRef ref (_ <> s) pure s bracketAction s = generalBracket (action s) - { killed: \error s' → void $ action (s' <> "/kill/" <> message error) - , failed: \error s' → void $ action (s' <> "/throw/" <> message error) - , completed: \r s' → void $ action (s' <> "/release/" <> r) + { killed: \error s' -> void $ action (s' <> "/kill/" <> message error) + , failed: \error s' -> void $ action (s' <> "/throw/" <> message error) + , completed: \r s' -> void $ action (s' <> "/release/" <> r) } - f1 ← forkAff $ bracketAction "foo" (const (action "a")) + f1 <- forkAff $ bracketAction "foo" (const (action "a")) delay (Milliseconds 5.0) killFiber (error "z") f1 - r1 ← try $ joinFiber f1 + r1 <- try $ joinFiber f1 - f2 ← forkAff $ bracketAction "bar" (const (throwError $ error "b")) - r2 ← try $ joinFiber f2 + f2 <- forkAff $ bracketAction "bar" (const (throwError $ error "b")) + r2 <- try $ joinFiber f2 - f3 ← forkAff $ bracketAction "baz" (const (action "c")) - r3 ← try $ joinFiber f3 + f3 <- forkAff $ bracketAction "baz" (const (action "c")) + r3 <- try $ joinFiber f3 - r4 ← readRef ref + r4 <- readRef ref pure (isLeft r1 && isLeft r2 && isRight r3 && r4 == "foofoo/kill/zbarbar/throw/bbazcbaz/release/c") -test_supervise ∷ Aff Unit +test_supervise :: Aff Unit test_supervise = assert "supervise" do - ref ← newRef "" - r1 ← supervise do - _ ← forkAff do + ref <- newRef "" + r1 <- supervise do + _ <- forkAff do bracket (modifyRef ref (_ <> "acquire")) - (\_ → void $ modifyRef ref (_ <> "release")) - (\_ → delay (Milliseconds 10.0)) - _ ← forkAff do + (\_ -> void $ modifyRef ref (_ <> "release")) + (\_ -> delay (Milliseconds 10.0)) + _ <- forkAff do delay (Milliseconds 11.0) void $ modifyRef ref (_ <> "delay") delay (Milliseconds 5.0) - _ ← modifyRef ref (_ <> "done") + _ <- modifyRef ref (_ <> "done") pure "done" delay (Milliseconds 20.0) - r2 ← readRef ref + r2 <- readRef ref pure (r1 == "done" && r2 == "acquiredonerelease") -test_kill ∷ Aff Unit +test_kill :: Aff Unit test_kill = assert "kill" do - fiber ← forkAff never + fiber <- forkAff never killFiber (error "Nope") fiber isLeft <$> try (joinFiber fiber) -test_kill_canceler ∷ Aff Unit +test_kill_canceler :: Aff Unit test_kill_canceler = assert "kill/canceler" do - ref ← newRef "" - fiber ← forkAff do - _ ← makeAff \_ → pure $ Canceler \_ → do + ref <- newRef "" + fiber <- forkAff do + _ <- makeAff \_ -> pure $ Canceler \_ -> do delay (Milliseconds 20.0) liftEffect (writeRef ref "cancel") writeRef ref "done" delay (Milliseconds 10.0) killFiber (error "Nope") fiber - res ← try (joinFiber fiber) - n ← readRef ref + res <- try (joinFiber fiber) + n <- readRef ref pure (n == "cancel" && (lmap message res) == Left "Nope") -test_kill_bracket ∷ Aff Unit +test_kill_bracket :: Aff Unit test_kill_bracket = assert "kill/bracket" do - ref ← newRef "" + ref <- newRef "" let action n = do delay (Milliseconds 10.0) void $ modifyRef ref (_ <> n) - fiber ← + fiber <- forkAff $ bracket (action "a") - (\_ → action "b") - (\_ → action "c") + (\_ -> action "b") + (\_ -> action "c") delay (Milliseconds 5.0) killFiber (error "Nope") fiber - _ ← try (joinFiber fiber) + _ <- try (joinFiber fiber) eq "ab" <$> readRef ref -test_kill_bracket_nested ∷ Aff Unit +test_kill_bracket_nested :: Aff Unit test_kill_bracket_nested = assert "kill/bracket/nested" do - ref ← newRef [] + ref <- newRef [] let action s = do delay (Milliseconds 10.0) - _ ← modifyRef ref (_ <> [ s ]) + _ <- modifyRef ref (_ <> [ s ]) pure s bracketAction s = bracket (action (s <> "/bar")) - (\s' → void $ action (s' <> "/release")) - (\s' → action (s' <> "/run")) - fiber ← + (\s' -> void $ action (s' <> "/release")) + (\s' -> action (s' <> "/run")) + fiber <- forkAff $ bracket (bracketAction "foo") - (\s → void $ bracketAction (s <> "/release")) - (\s → bracketAction (s <> "/run")) + (\s -> void $ bracketAction (s <> "/release")) + (\s -> bracketAction (s <> "/run")) delay (Milliseconds 5.0) killFiber (error "Nope") fiber - _ ← try (joinFiber fiber) + _ <- try (joinFiber fiber) readRef ref <#> eq [ "foo/bar" , "foo/bar/run" @@ -344,24 +344,25 @@ test_kill_bracket_nested = assert "kill/bracket/nested" do , "foo/bar/run/release/bar/release" ] -test_kill_general_bracket_nested ∷ Aff Unit +test_kill_general_bracket_nested :: Aff Unit test_kill_general_bracket_nested = assert "kill/bracket/general/nested" do ref <- newRef [] let action s = do - _ ← modifyRef ref (_ <> [ s ]) + _ <- modifyRef ref (_ <> [ s ]) pure unit bracketAction s acq = generalBracket acq - { killed: \_ _ → action (s <> "/killed") - , failed: \_ _ → action (s <> "/failed") - , completed: \_ _ → action (s <> "/completed") + { killed: \_ _ -> action (s <> "/killed") + , failed: \_ _ -> action (s <> "/failed") + , completed: \_ _ -> action (s <> "/completed") } - (\_ → do - delay (Milliseconds 10.0) - action (s <> "/run")) - fiber ← forkAff do + ( \_ -> do + delay (Milliseconds 10.0) + action (s <> "/run") + ) + fiber <- forkAff do bracketAction "outer" do action "outer/acquire" bracketAction "inner" do @@ -377,22 +378,23 @@ test_kill_general_bracket_nested = assert "kill/bracket/general/nested" do , "outer/killed" ] -test_kill_supervise ∷ Aff Unit +test_kill_supervise :: Aff Unit test_kill_supervise = assert "kill/supervise" do - ref ← newRef "" + ref <- newRef "" let action s = generalBracket (modifyRef ref (_ <> "acquire" <> s)) - { failed: \_ _ → void $ modifyRef ref (_ <> "throw" <> s) - , killed: \_ _ → void $ modifyRef ref (_ <> "kill" <> s) - , completed: \_ _ → void $ modifyRef ref (_ <> "complete" <> s) + { failed: \_ _ -> void $ modifyRef ref (_ <> "throw" <> s) + , killed: \_ _ -> void $ modifyRef ref (_ <> "kill" <> s) + , completed: \_ _ -> void $ modifyRef ref (_ <> "complete" <> s) } - (\_ -> do - delay (Milliseconds 10.0) - void $ modifyRef ref (_ <> "child" <> s)) - fiber ← forkAff $ supervise do - _ ← forkAff $ action "foo" - _ ← forkAff $ action "bar" + ( \_ -> do + delay (Milliseconds 10.0) + void $ modifyRef ref (_ <> "child" <> s) + ) + fiber <- forkAff $ supervise do + _ <- forkAff $ action "foo" + _ <- forkAff $ action "bar" delay (Milliseconds 5.0) modifyRef ref (_ <> "parent") delay (Milliseconds 1.0) @@ -400,276 +402,283 @@ test_kill_supervise = assert "kill/supervise" do delay (Milliseconds 20.0) eq "acquirefooacquirebarkillfookillbar" <$> readRef ref -test_kill_finalizer_catch ∷ Aff Unit +test_kill_finalizer_catch :: Aff Unit test_kill_finalizer_catch = assert "kill/finalizer/catch" do - ref ← newRef "" - fiber ← forkAff $ bracket + ref <- newRef "" + fiber <- forkAff $ bracket (delay (Milliseconds 10.0)) - (\_ → throwError (error "Finalizer") `catchError` \_ → writeRef ref "caught") - (\_ → pure unit) + (\_ -> throwError (error "Finalizer") `catchError` \_ -> writeRef ref "caught") + (\_ -> pure unit) killFiber (error "Nope") fiber eq "caught" <$> readRef ref -test_kill_finalizer_bracket ∷ Aff Unit +test_kill_finalizer_bracket :: Aff Unit test_kill_finalizer_bracket = assert "kill/finalizer/bracket" do - ref ← newRef "" - fiber ← forkAff $ bracket + ref <- newRef "" + fiber <- forkAff $ bracket (delay (Milliseconds 10.0)) - (\_ → generalBracket (pure unit) - { killed: \_ _ → writeRef ref "killed" - , failed: \_ _ → writeRef ref "failed" - , completed: \_ _ → writeRef ref "completed" - } - (\_ → pure unit)) - (\_ → pure unit) + ( \_ -> generalBracket (pure unit) + { killed: \_ _ -> writeRef ref "killed" + , failed: \_ _ -> writeRef ref "failed" + , completed: \_ _ -> writeRef ref "completed" + } + (\_ -> pure unit) + ) + (\_ -> pure unit) killFiber (error "Nope") fiber eq "completed" <$> readRef ref -test_parallel ∷ Aff Unit +test_parallel :: Aff Unit test_parallel = assert "parallel" do - ref ← newRef "" + ref <- newRef "" let action s = do delay (Milliseconds 10.0) - _ ← modifyRef ref (_ <> s) + _ <- modifyRef ref (_ <> s) pure s - f1 ← forkAff $ sequential $ + f1 <- forkAff $ sequential $ { a: _, b: _ } <$> parallel (action "foo") <*> parallel (action "bar") delay (Milliseconds 15.0) - r1 ← readRef ref - r2 ← joinFiber f1 + r1 <- readRef ref + r2 <- joinFiber f1 pure (r1 == "foobar" && r2.a == "foo" && r2.b == "bar") -test_parallel_throw ∷ Aff Unit +test_parallel_throw :: Aff Unit test_parallel_throw = assert "parallel/throw" $ withTimeout (Milliseconds 100.0) do - ref ← newRef "" + ref <- newRef "" let action n s = do delay (Milliseconds n) - _ ← modifyRef ref (_ <> s) + _ <- modifyRef ref (_ <> s) pure s - r1 ← try $ sequential $ + r1 <- try $ sequential $ { a: _, b: _ } <$> parallel (action 10.0 "foo" *> throwError (error "Nope")) <*> parallel never - r2 ← readRef ref + r2 <- readRef ref pure (isLeft r1 && r2 == "foo") -test_kill_parallel ∷ Aff Unit +test_kill_parallel :: Aff Unit test_kill_parallel = assert "kill/parallel" do - ref ← newRef "" + ref <- newRef "" let action s = do bracket (pure unit) - (\_ → void $ modifyRef ref (_ <> "killed" <> s)) - (\_ → do - delay (Milliseconds 10.0) - void $ modifyRef ref (_ <> s)) - f1 ← forkAff $ sequential $ + (\_ -> void $ modifyRef ref (_ <> "killed" <> s)) + ( \_ -> do + delay (Milliseconds 10.0) + void $ modifyRef ref (_ <> s) + ) + f1 <- forkAff $ sequential $ parallel (action "foo") *> parallel (action "bar") - f2 ← forkAff do + f2 <- forkAff do delay (Milliseconds 5.0) killFiber (error "Nope") f1 modifyRef ref (_ <> "done") - _ ← try $ joinFiber f1 - _ ← try $ joinFiber f2 + _ <- try $ joinFiber f1 + _ <- try $ joinFiber f2 eq "killedfookilledbardone" <$> readRef ref -test_parallel_alt ∷ Aff Unit +test_parallel_alt :: Aff Unit test_parallel_alt = assert "parallel/alt" do - ref ← newRef "" + ref <- newRef "" let action n s = do delay (Milliseconds n) - _ ← modifyRef ref (_ <> s) + _ <- modifyRef ref (_ <> s) pure s - f1 ← forkAff $ sequential $ + f1 <- forkAff $ sequential $ parallel (action 10.0 "foo") <|> parallel (action 5.0 "bar") delay (Milliseconds 10.0) - r1 ← readRef ref - r2 ← joinFiber f1 + r1 <- readRef ref + r2 <- joinFiber f1 pure (r1 == "bar" && r2 == "bar") -test_parallel_alt_throw ∷ Aff Unit +test_parallel_alt_throw :: Aff Unit test_parallel_alt_throw = assert "parallel/alt/throw" do - r1 ← sequential $ + r1 <- sequential $ parallel (delay (Milliseconds 10.0) *> throwError (error "Nope.")) - <|> parallel (delay (Milliseconds 11.0) $> "foo") - <|> parallel (delay (Milliseconds 12.0) $> "bar") + <|> parallel (delay (Milliseconds 11.0) $> "foo") + <|> parallel (delay (Milliseconds 12.0) $> "bar") pure (r1 == "foo") -test_parallel_alt_sync ∷ Aff Unit +test_parallel_alt_sync :: Aff Unit test_parallel_alt_sync = assert "parallel/alt/sync" do - ref ← newRef "" + ref <- newRef "" let action s = do bracket (pure unit) - (\_ → void $ modifyRef ref (_ <> "killed" <> s)) - (\_ → modifyRef ref (_ <> s) $> s) - r1 ← sequential $ + (\_ -> void $ modifyRef ref (_ <> "killed" <> s)) + (\_ -> modifyRef ref (_ <> s) $> s) + r1 <- sequential $ parallel (action "foo") - <|> parallel (action "bar") - <|> parallel (action "baz") - r2 ← readRef ref + <|> parallel (action "bar") + <|> parallel (action "baz") + r2 <- readRef ref pure (r1 == "foo" && r2 == "fookilledfoo") -test_parallel_mixed ∷ Aff Unit +test_parallel_mixed :: Aff Unit test_parallel_mixed = assert "parallel/mixed" do - ref ← newRef "" + ref <- newRef "" let action n s = parallel do delay (Milliseconds n) - _ ← modifyRef ref (_ <> s) + _ <- modifyRef ref (_ <> s) pure s - { r1, r2, r3 } ← sequential $ + { r1, r2, r3 } <- sequential $ { r1: _, r2: _, r3: _ } <$> action 10.0 "a" - <*> (action 15.0 "a" + <*> + ( action 15.0 "a" <|> action 12.0 "b" - <|> action 16.0 "c") - <*> (action 15.0 "a" + <|> action 16.0 "c" + ) + <*> + ( action 15.0 "a" <|> ((<>) <$> action 13.0 "d" <*> action 14.0 "e") - <|> action 16.0 "f") + <|> action 16.0 "f" + ) delay (Milliseconds 20.0) - r4 ← readRef ref + r4 <- readRef ref pure (r1 == "a" && r2 == "b" && r3 == "de" && r4 == "abde") -test_kill_parallel_alt ∷ Aff Unit +test_kill_parallel_alt :: Aff Unit test_kill_parallel_alt = assert "kill/parallel/alt" do - ref ← newRef "" + ref <- newRef "" let action n s = do bracket (pure unit) - (\_ → void $ modifyRef ref (_ <> "killed" <> s)) - (\_ → do - delay (Milliseconds n) - void $ modifyRef ref (_ <> s)) - f1 ← forkAff $ sequential $ + (\_ -> void $ modifyRef ref (_ <> "killed" <> s)) + ( \_ -> do + delay (Milliseconds n) + void $ modifyRef ref (_ <> s) + ) + f1 <- forkAff $ sequential $ parallel (action 10.0 "foo") <|> parallel (action 20.0 "bar") - f2 ← forkAff do + f2 <- forkAff do delay (Milliseconds 5.0) killFiber (error "Nope") f1 modifyRef ref (_ <> "done") - _ ← try $ joinFiber f1 - _ ← try $ joinFiber f2 + _ <- try $ joinFiber f1 + _ <- try $ joinFiber f2 eq "killedfookilledbardone" <$> readRef ref -test_kill_parallel_alt_finalizer ∷ Aff Unit +test_kill_parallel_alt_finalizer :: Aff Unit test_kill_parallel_alt_finalizer = assert "kill/parallel/alt/finalizer" do - ref ← newRef "" - f1 ← forkAff $ sequential $ + ref <- newRef "" + f1 <- forkAff $ sequential $ parallel (delay (Milliseconds 10.0)) <|> parallel do bracket (pure unit) - (\_ → do - delay (Milliseconds 10.0) - void $ modifyRef ref (_ <> "killed")) - (\_ → delay (Milliseconds 20.0)) - f2 ← forkAff do + ( \_ -> do + delay (Milliseconds 10.0) + void $ modifyRef ref (_ <> "killed") + ) + (\_ -> delay (Milliseconds 20.0)) + f2 <- forkAff do delay (Milliseconds 15.0) killFiber (error "Nope") f1 modifyRef ref (_ <> "done") - _ ← try $ joinFiber f1 - _ ← try $ joinFiber f2 + _ <- try $ joinFiber f1 + _ <- try $ joinFiber f2 eq "killeddone" <$> readRef ref -test_fiber_map ∷ Aff Unit +test_fiber_map :: Aff Unit test_fiber_map = assert "fiber/map" do - ref ← newRef 0 + ref <- newRef 0 let mapFn a = unsafePerformEffect do - _ ← Ref.modify (_ + 1) ref + _ <- Ref.modify (_ + 1) ref pure (a + 1) - f1 ← forkAff do + f1 <- forkAff do delay (Milliseconds 10.0) pure 10 let f2 = mapFn <$> f1 - a ← joinFiber f2 - b ← joinFiber f2 - n ← readRef ref + a <- joinFiber f2 + b <- joinFiber f2 + n <- readRef ref pure (a == 11 && b == 11 && n == 1) -test_fiber_apply ∷ Aff Unit +test_fiber_apply :: Aff Unit test_fiber_apply = assert "fiber/apply" do - ref ← newRef 0 + ref <- newRef 0 let applyFn a b = unsafePerformEffect do - _ ← Ref.modify (_ + 1) ref + _ <- Ref.modify (_ + 1) ref pure (a + b) - f1 ← forkAff do + f1 <- forkAff do delay (Milliseconds 10.0) pure 10 - f2 ← forkAff do + f2 <- forkAff do delay (Milliseconds 15.0) pure 12 let f3 = applyFn <$> f1 <*> f2 - a ← joinFiber f3 - b ← joinFiber f3 - n ← readRef ref + a <- joinFiber f3 + b <- joinFiber f3 + n <- readRef ref pure (a == 22 && b == 22 && n == 1) -test_efffn ∷ Aff Unit +test_efffn :: Aff Unit test_efffn = assert "efffn" do - ref ← newRef "" + ref <- newRef "" let - effectDelay ms = AC.fromEffectFnAff $ AC.EffectFnAff $ AC.mkEffectFn2 \ke kc → do - fiber ← runAff (either (AC.runEffectFn1 ke) (AC.runEffectFn1 kc)) (delay ms) - pure $ AC.EffectFnCanceler $ AC.mkEffectFn3 \e cke ckc → do + effectDelay ms = AC.fromEffectFnAff $ AC.EffectFnAff $ AC.mkEffectFn2 \ke kc -> do + fiber <- runAff (either (AC.runEffectFn1 ke) (AC.runEffectFn1 kc)) (delay ms) + pure $ AC.EffectFnCanceler $ AC.mkEffectFn3 \e cke ckc -> do runAff_ (either (AC.runEffectFn1 cke) (AC.runEffectFn1 ckc)) (killFiber e fiber) action = do effectDelay (Milliseconds 10.0) void $ modifyRef ref (_ <> "done") - _ ← forkAff action - f2 ← forkAff action + _ <- forkAff action + f2 <- forkAff action killFiber (error "Nope.") f2 delay (Milliseconds 20.0) eq "done" <$> readRef ref -test_parallel_stack ∷ Aff Unit +test_parallel_stack :: Aff Unit test_parallel_stack = assert "parallel/stack" do - ref ← newRef 0 + ref <- newRef 0 parTraverse_ (modifyRef ref <<< add) (Array.replicate 100000 1) eq 100000 <$> readRef ref -test_scheduler_size ∷ Aff Unit +test_scheduler_size :: Aff Unit test_scheduler_size = assert "scheduler" do - ref ← newRef 0 - _ ← traverse joinFiber =<< traverse forkAff (Array.replicate 100000 (modifyRef ref (add 1))) + ref <- newRef 0 + _ <- traverse joinFiber =<< traverse forkAff (Array.replicate 100000 (modifyRef ref (add 1))) eq 100000 <$> readRef ref -test_lazy ∷ Aff Unit +test_lazy :: Aff Unit test_lazy = assert "Lazy Aff" do - ref ← newRef 0 + ref <- newRef 0 fix \loop -> do - val ← readRef ref - if val < 10 - then do - writeRef ref (val + 1) - loop - else - pure unit + val <- readRef ref + if val < 10 then do + writeRef ref (val + 1) + loop + else + pure unit eq 10 <$> readRef ref -test_regression_return_fork ∷ Aff Unit +test_regression_return_fork :: Aff Unit test_regression_return_fork = assert "regression/return-fork" do bracket (forkAff (pure unit)) (const (pure unit)) (const (pure true)) -test_regression_par_apply_async_canceler ∷ Aff Unit +test_regression_par_apply_async_canceler :: Aff Unit test_regression_par_apply_async_canceler = assert "regression/par-apply-async-canceler" do - ref ← newRef "" + ref <- newRef "" let - action1 = makeAff \_ → - pure $ Canceler \_ → do + action1 = makeAff \_ -> + pure $ Canceler \_ -> do delay (Milliseconds 10.0) void $ modifyRef ref (_ <> "done") @@ -684,30 +693,30 @@ test_regression_par_apply_async_canceler = assert "regression/par-apply-async-ca val <- readRef ref pure (val == "throwdone" && message err == "Nope.") -test_regression_bracket_catch_cleanup ∷ Aff Unit +test_regression_bracket_catch_cleanup :: Aff Unit test_regression_bracket_catch_cleanup = assert "regression/bracket-catch-cleanup" do - res :: Either Error Unit ← + res :: Either Error Unit <- try $ bracket (pure unit) - (\_ → catchError (pure unit) (const (pure unit))) - (\_ → throwError (error "Nope.")) + (\_ -> catchError (pure unit) (const (pure unit))) + (\_ -> throwError (error "Nope.")) pure $ lmap message res == Left "Nope." -test_regression_kill_sync_async ∷ Aff Unit +test_regression_kill_sync_async :: Aff Unit test_regression_kill_sync_async = assert "regression/kill-sync-async" do - _ ← newRef "" - f1 ← forkAff $ makeAff \k -> k (Left (error "Boom.")) *> mempty + _ <- newRef "" + f1 <- forkAff $ makeAff \k -> k (Left (error "Boom.")) *> mempty killFiber (error "Nope.") f1 pure true -test_regression_bracket_kill_mask ∷ Aff Unit +test_regression_bracket_kill_mask :: Aff Unit test_regression_bracket_kill_mask = assert "regression/kill-bracket-mask" do - ref ← newRef "" + ref <- newRef "" let action s = do _ <- modifyRef ref (_ <> s) pure unit - fiber ← forkAff do + fiber <- forkAff do bracket do action "a" @@ -722,15 +731,15 @@ test_regression_bracket_kill_mask = assert "regression/kill-bracket-mask" do killFiber (error "nope") fiber readRef ref <#> eq "ab" -test_regression_kill_empty_supervisor ∷ Aff Unit +test_regression_kill_empty_supervisor :: Aff Unit test_regression_kill_empty_supervisor = assert "regression/kill-empty-supervisor" do - f1 ← forkAff $ supervise $ delay $ Milliseconds 10.0 + f1 <- forkAff $ supervise $ delay $ Milliseconds 10.0 let a = parallel $ killFiber (error "Nope.") f1 $> true b = parallel $ delay (Milliseconds 20.0) $> false sequential (a <|> b) -main ∷ Effect Unit +main :: Effect Unit main = do test_pure test_bind From 3543788c5109f3f9d32e2890f880c451bed2f5b1 Mon Sep 17 00:00:00 2001 From: Thomas Honeyman Date: Thu, 11 Nov 2021 11:39:13 +0100 Subject: [PATCH 3/4] fixup formatting --- src/Effect/Aff.purs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/Effect/Aff.purs b/src/Effect/Aff.purs index 21ff748..4854444 100644 --- a/src/Effect/Aff.purs +++ b/src/Effect/Aff.purs @@ -179,9 +179,12 @@ instance applicativeFiber :: Applicative Fiber where -- | Invokes pending cancelers in a fiber and runs cleanup effects. Blocks -- | until the fiber has fully exited. killFiber :: forall a. Error -> Fiber a -> Aff Unit -killFiber e (Fiber t) = liftEffect t.isSuspended >>= - if _ then liftEffect $ void $ Fn.runFn2 t.kill e (const (pure unit)) - else makeAff \k -> effectCanceler <$> Fn.runFn2 t.kill e k +killFiber e (Fiber t) = do + suspended <- liftEffect t.isSuspended + if suspended then + liftEffect $ void $ Fn.runFn2 t.kill e (const (pure unit)) + else + makeAff \k -> effectCanceler <$> Fn.runFn2 t.kill e k -- | Blocks until the fiber completes, yielding the result. If the fiber -- | throws an exception, it is rethrown in the current fiber. From f0dc3b319cd58e4a0d6542ca903e1d0d2be194f9 Mon Sep 17 00:00:00 2001 From: Thomas Honeyman Date: Thu, 11 Nov 2021 11:40:27 +0100 Subject: [PATCH 4/4] another small tweak --- test/Test/Bench.purs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/Test/Bench.purs b/test/Test/Bench.purs index b68f28a..650c4e8 100644 --- a/test/Test/Bench.purs +++ b/test/Test/Bench.purs @@ -46,7 +46,8 @@ loop2 = go fib1 :: Int -> Aff.Aff Int fib1 n = - if n <= 1 then pure n + if n <= 1 then + pure n else do a <- fib1 (n - 1) b <- fib1 (n - 2)