packages feed

bluefin-internal 0.0.8.0 → 0.0.9.0

raw patch · 5 files changed

+98/−16 lines, 5 filesdep ~asyncPVP ok

version bump matches the API change (PVP)

Dependency ranges changed: async

API changes (from Hackage documentation)

+ Bluefin.Internal: instance Bluefin.Internal.Handle Bluefin.Internal.IOE
+ Bluefin.Internal: rethrowIO :: forall ex es e1 e2 r. (e1 :> es, e2 :> es, Exception ex) => IOE e1 -> Exception ex e2 -> Eff es r -> Eff es r
+ Bluefin.Internal.Examples: doubleNestedForEach :: (forall e. Stream () e -> Eff (e :& es) ()) -> Eff es ()
+ Bluefin.Internal.Examples: rethrowIOExample :: IO ()

Files

CHANGELOG.md view
@@ -1,3 +1,9 @@+## 0.0.9.0++* Add `instance Handle IOE`++* Add `rethrowIO`+ ## 0.0.8.0  Add `Consume`, `await`, `consumeStream`, `zipCoroutines`,
bluefin-internal.cabal view
@@ -1,6 +1,6 @@ cabal-version:      3.0 name:               bluefin-internal-version:            0.0.8.0+version:            0.0.9.0 license:            MIT license-file:       LICENSE author:             Tom Ellis@@ -77,7 +77,7 @@     default-language: Haskell2010     hs-source-dirs: src     build-depends:-      async,+      async >= 2.2 && < 2.3,       base >= 4.12 && < 4.21,       unliftio-core < 0.3,       transformers < 0.7,
src/Bluefin/Internal.hs view
@@ -243,7 +243,7 @@ insertFirst = weakenEff (drop (eq (# #)))  insertSecond :: Eff (c1 :& b) r -> Eff (c1 :& (c2 :& b)) r-insertSecond = weakenEff (b (drop (eq (# #))))+insertSecond = insertManySecond  insertManySecond :: (b :> c) => Eff (c1 :& b) r -> Eff (c1 :& c) r insertManySecond = weakenEff (bimap has has)@@ -355,6 +355,9 @@ instance Handle (Writer w) where   mapHandle (Writer wr) = Writer (mapHandle wr) +instance Handle IOE where+  mapHandle MkIOE = MkIOE+ newtype In (a :: Effects) (b :: Effects) = In# (# #)  merge :: (# #) -> (a :& a) `In` a@@ -489,6 +492,51 @@   (exn -> Eff es a) ->   Eff es a catch f h = handle h f++-- We really do need to have an IOE argument here because, it is not+-- determined which of Ex1 or Ex2 is produced in the following code,+-- due to pure exceptions being imprecise.+--+-- f :: IO (Either Ex1 (Either Ex2 a))+-- f = runEff $ \io -> do+--   try $ \e1 -> do+--     try $ \e2 -> do+--       rethrowIO io e1 $ do+--         rethrowIO io e2 $ doa+--           Control.Exception.throw Ex1) (Control.Exception.throw E2)++-- | Rethrow an exception raised by an 'IO' action as a Bluefin+-- exception.+--+-- @+-- 'runEff' $ \\io -> do+--   r \<- 'try' $ \\ex -> do+--     rethrowIO @'Control.Exception.IOException' io ex $ do+--       effIO io ('Prelude.readFile' "\/tmp\/doesnt-exist")+--+--   'effIO' io $ putStrLn $ case r of+--     Left e -> "Caught IOException:\\n" ++ show e+--     Right contents -> contents+-- @+--+-- @+-- Caught ErrorCall:+-- \/tmp\/doesnt-exist: openFile: does not exist (No such file or directory)+-- @+rethrowIO ::+  forall ex es e1 e2 r.+  (e1 :> es, e2 :> es, Control.Exception.Exception ex) =>+  IOE e1 ->+  Exception ex e2 ->+  Eff es r ->+  -- | ͘+  Eff es r+rethrowIO MkIOE ex body =+  UnsafeMkEff+    ( Control.Exception.catch+        (unsafeUnEff body)+        (\e -> unsafeUnEff (throw @_ @es ex e))+    )  -- | @bracket acquire release body@: @acquire@ a resource, perform the -- @body@ with it, and @release@ the resource even if @body@ threw an
src/Bluefin/Internal/Examples.hs view
@@ -77,6 +77,17 @@   yield y 100   pure length +-- This shows we can use forEach at any level of nesting with+-- insertManySecond+doubleNestedForEach ::+  (forall e. Stream () e -> Eff (e :& es) ()) ->+  Eff es ()+doubleNestedForEach f =+  withState () $ \_ -> do+    withState () $ \_ -> do+      forEach (insertManySecond . f) (\_ -> pure ())+      pure (\_ _ -> ())+ forEachExample :: ([Int], ()) forEachExample = runPureEff $ yieldToList $ \y -> do   forEach (inFoldable [0 .. 4]) $ \i -> do@@ -877,3 +888,13 @@           (\_ -> for_ [1 :: Int ..] $ \i -> yield y i)     )   effIO io (putStrLn "Finishing")++rethrowIOExample :: IO ()+rethrowIOExample = runEff $ \io -> do+  r <- try $ \ex -> do+    rethrowIO @Control.Exception.IOException io ex $ do+      effIO io (Prelude.readFile "/tmp/doesnt-exist")++  effIO io $ putStrLn $ case r of+    Left e -> "Caught IOException:\n" ++ show e+    Right contents -> contents
test/Main.hs view
@@ -11,8 +11,8 @@ import Prelude hiding (break, read)  main :: IO ()-main = do-  runSpecH $ \y -> do+main = runEff $ \io -> do+  runSpecH io $ \y -> do     let assertEqual' = assertEqual y      assertEqual' "oddsUntilFirstGreaterThan5" oddsUntilFirstGreaterThan5 [1, 3, 5, 7]@@ -53,26 +53,31 @@           yield y2 ("But got: " ++ show c2)     ) -type SpecInfo = Forall (Nest (Stream String) Eff)+type SpecInfo r = Forall (Stream String :~> WrapEff r)  withSpecInfo ::   (forall e es. (e :> es) => Stream String e -> Eff es r) ->   SpecInfo r-withSpecInfo x = Forall (Nest x)+withSpecInfo x = Forall (Nest (\s -> MkWrapEff (x s))) -newtype Nest h t es r = Nest {unNest :: forall e. (e :> es) => h e -> t es r}+newtype (h :~> t) es = Nest {unNest :: forall e. h e -> t (e :& es)} -newtype Forall t r = Forall {unForall :: forall es. t es r}+newtype Forall t = Forall {unForall :: forall es. t es} +newtype WrapEff r es = MkWrapEff {unWrapEff :: Eff es r}++instance Handle (WrapEff r) where+  mapHandle (MkWrapEff e) = MkWrapEff (useImpl e)+ runTests ::   forall es e3.   (e3 :> es) =>-  (forall e1 e2. SpecH e1 -> Eff (e1 :& e2 :& es) ()) ->+  (forall e1. SpecH e1 -> Eff (e1 :& es) ()) ->   Stream String e3 ->   Eff es Bool runTests f y = do   ((), All passedAll) <- runWriter $ \passedAllSoFar -> do-    forEach f $ \(name, mFailure) -> do+    forEach (useImplWithin f) $ \(name, mFailure) -> do       let passed = case mFailure of             Just _ -> False             Nothing -> True@@ -87,17 +92,19 @@         Nothing -> pure ()         Just n -> do           yield y "" :: Eff (e2 :& es) ()-          _ <- forEach (unNest (unForall n)) $ \entry -> do+          _ <- forEach (unWrapEff . unNest (unForall n)) $ \entry -> do             yield y ("    " ++ entry)           yield y ""    pure passedAll  runSpecH ::-  (forall e1 es. SpecH e1 -> Eff (e1 :& es) ()) ->-  IO ()-runSpecH f = runEff $ \ioe -> do-  passed <- forEach (runTests f) $ \text ->+  (e :> es) =>+  IOE e ->+  (forall e1. SpecH e1 -> Eff (e1 :& es) ()) ->+  Eff es ()+runSpecH ioe f = do+  passed <- forEach (runTests (useImplWithin f)) $ \text ->     effIO ioe (putStrLn text)    effIO ioe $ case passed of