packages feed

bluefin 0.2.3.0 → 0.2.4.0

raw patch · 4 files changed

+102/−3 lines, 4 filesdep ~bluefin-internalPVP ok

version bump matches the API change (PVP)

Dependency ranges changed: bluefin-internal

API changes (from Hackage documentation)

+ Bluefin.CloneableHandle: MkGenericCloneableHandle :: h e -> GenericCloneableHandle (h :: k -> Type) (e :: k)
+ Bluefin.CloneableHandle: class Handle h => CloneableHandle (h :: Effects -> Type)
+ Bluefin.CloneableHandle: class Handle h => GCloneableHandle (h :: Effects -> Type)
+ Bluefin.CloneableHandle: class Generic1 (f :: k -> Type)
+ Bluefin.CloneableHandle: newtype GenericCloneableHandle (h :: k -> Type) (e :: k)
+ Bluefin.CloneableHandle: withEffToIOCloneHandle :: forall (e1 :: Effects) (es :: Effects) h a. (e1 :> es, CloneableHandle h) => IOE e1 -> h es -> ((forall r. () => (forall (e :: Effects). () => IOE e -> h e -> Eff e r) -> IO r) -> IO a) -> Eff es a
+ Bluefin.IO: withEffToIOCloneHandle :: forall (e1 :: Effects) (es :: Effects) h a. (e1 :> es, CloneableHandle h) => IOE e1 -> h es -> ((forall r. () => (forall (e :: Effects). () => IOE e -> h e -> Eff e r) -> IO r) -> IO a) -> Eff es a

Files

CHANGELOG.md view
@@ -1,4 +1,8 @@-# 0.2.1.0+# 0.2.4.0++* Add `Bluefin.CloneHandle` and `Bluefin.IO.withEffToIOCloneHandle`++# 0.2.3.0  * Add `Bluefin.DslBuilder` 
bluefin.cabal view
@@ -1,6 +1,6 @@ cabal-version:      3.0 name:               bluefin-version:            0.2.3.0+version:            0.2.4.0 license:            MIT license-file:       LICENSE author:             Tom Ellis@@ -24,6 +24,7 @@       Bluefin.Compound,       Bluefin.Consume,       Bluefin.Coroutine,+      Bluefin.CloneableHandle,       Bluefin.DslBuilder,       Bluefin.EarlyReturn,       Bluefin.Eff,@@ -40,6 +41,6 @@       Bluefin.System.IO,       Bluefin.Writer,     build-depends:-      bluefin-internal >= 0.3.1.0 && < 0.4+      bluefin-internal >= 0.3.2.0 && < 0.4     hs-source-dirs:   src     default-language: Haskell2010
+ src/Bluefin/CloneableHandle.hs view
@@ -0,0 +1,92 @@+-- | @Bluefin.CloneableHandle@ defines the 'CloneableHandle' class,+-- whose purpose is to support 'withEffToIOCloneHandle'.++module Bluefin.CloneableHandle+  ( -- | 'withEffToIOCloneHandle' is an @IO@ unlifting function that+    -- clones its handle each time it runs @Eff@ in @IO@.  This is+    -- convenient when the unlifting function is being used to fork+    -- threads, since Bluefin state is not threadsafe.  Be careful+    -- when you use it, because it can be used to throw away the+    -- effect tag on a Bluefin @Eff@ action due to this part of+    -- its type (here throwing away @e@):+    --+    -- @+    -- (forall e. IOE e -> h e -> Eff e r) -> IO r+    -- @+    --+    -- It is only safely used when you do not allow any effects to+    -- escape their scope, so we suggest that you use it sparingly to+    -- define reusable combinators which themselves are safe.  For+    -- example, here is how you could write an equivalent of @async@'s+    -- @race@ primitive:+    --+    -- @+    -- bluefinRace ::+    --   ('CloneableHandle' h, e1 :> es) =>+    --   t'Bluefin.IO.IOE' e1 ->+    --   h es ->+    --   (forall e. IOE e -> h e -> t'Bluefin.Eff.Eff' e r) ->+    --   (forall e. IOE e -> h e -> Eff e r) ->+    --   Eff es r+    -- bluefinRace io h m1 m2 = withEffToIOCloneHandle io h $ \\runInIO -> do+    --  either id id+    --    \<$\> Control.Concurrent.Async.race+    --      (runInIO $ \\io' h' -> m1 io' h')+    --      (runInIO $ \\io' h' -> m2 io' h')+    -- @+    --+    -- Then you can safely use it to race Bluefin @Eff@ actions:+    --+    -- @+    -- example :: IO ()+    -- example = 'Bluefin.Eff.runEff_' $ \\io -> 'Bluefin.State.evalState' 0 $ \\st -> do+    --   r \<- 'Bluefin.Exception.try' $ \\ex -> do+    --     bluefinRace+    --       io+    --       (MkMyHandle ('Bluefin.Handle.mapHandle' ex) (mapHandle st))+    --       ( \\_ (MkMyHandle ex' st') -> do+    --           'Bluefin.State.modify' st' (subtract 2000)+    --           'Bluefin.Exception.throw' ex' "Aborting from branch 1"+    --       )+    --       ( \\_ (MkMyHandle _ st') -> do+    --           modify st' (+ 3000)+    --           pure (2 :: Int)+    --       )+    --+    --   s <- 'Bluefin.State.get' st+    --   'Bluefin.IO.effIO' io (print r)+    --   effIO io (putStrLn ("State started at 0 and was cloned. Now: " <> show s))+    -- @+    --+    -- You can see from the output that the actions were raced as+    -- expected, and the @State@ was cloned so that changes to it in+    -- the branches of @race@ did not affect the original @State@.+    --+    -- @+    -- -- Run one time (the first thread was faster)+    -- ghci> example+    -- Right 2+    -- State started at 0 and was cloned. Now: 0+    -- -- Run another time (the second thread was faster)+    -- ghci> example+    -- Left "Aborting from branch 1"+    -- State started at 0 and was cloned. Now: 0+    -- @+    --+    -- Note that @withEffToIOCloneHandle@ only allows access to /one/+    -- external @Handle@ within it, so if you have several you'd like+    -- to use you'll have to define a new handle that bundles them+    -- together.+    withEffToIOCloneHandle,++    -- * @CloneableHandle@+    CloneableHandle,+    GenericCloneableHandle(MkGenericCloneableHandle),+    GCloneableHandle,++    -- * @GHC.Generics@ re-exports+    Generic1,+  )+where++import Bluefin.Internal.CloneableHandle
src/Bluefin/IO.hs view
@@ -12,6 +12,7 @@     -- * IO type classes     withMonadIO,     withEffToIO_,+    withEffToIOCloneHandle,     -- ** @EffReader@     EffReader,     effReader,@@ -22,3 +23,4 @@ where  import Bluefin.Internal+import Bluefin.Internal.CloneableHandle