| Safe Haskell | Safe-Inferred |
|---|---|
| Language | Haskell2010 |
Bluefin.CloneableHandle
Description
Bluefin.CloneableHandle defines the CloneableHandle class,
whose purpose is to support withEffToIOCloneHandle.
Synopsis
- 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
- class Handle h => CloneableHandle (h :: Effects -> Type)
- newtype GenericCloneableHandle (h :: k -> Type) (e :: k) = MkGenericCloneableHandle (h e)
- class Handle h => GCloneableHandle (h :: Effects -> Type)
- class Generic1 (f :: k -> Type)
Documentation
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 :: (CloneableHandleh, e1 <: es) =>IOEe1 -> h es -> (forall e. IOE e -> h e ->Effe 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 =runEff$ \io ->evalState0 $ \st -> do r <-try$ \ex -> do bluefinRace io (MkMyHandle (mapHandleex) (mapHandle st)) ( \_ (MkMyHandle ex' st') -> domodifyst' (subtract 2000)throwex' "Aborting from branch 1" ) ( \_ (MkMyHandle _ st') -> do modify st' (+ 3000) pure (2 :: Int) ) s <-getsteffIOio (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 :: 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 #
CloneableHandle
class Handle h => CloneableHandle (h :: Effects -> Type) #
Minimal complete definition
cloneableHandleImpl
Instances
newtype GenericCloneableHandle (h :: k -> Type) (e :: k) #
Constructors
| MkGenericCloneableHandle (h e) |
Instances
| (Handle h, e <: es) => OneWayCoercible (GenericCloneableHandle h e :: Type) (GenericCloneableHandle h es :: Type) | |
Defined in Bluefin.Internal.CloneableHandle Methods oneWayCoercibleImpl :: OneWayCoercibleD (GenericCloneableHandle h e) (GenericCloneableHandle h es) # | |
| Handle h => Handle (GenericCloneableHandle h) | |
Defined in Bluefin.Internal.CloneableHandle Methods handleImpl :: HandleD (GenericCloneableHandle h) # | |
| (Handle h, Generic1 h, GCloneableHandle (Rep1 h)) => CloneableHandle (GenericCloneableHandle h) | |
Defined in Bluefin.Internal.CloneableHandle Methods cloneableHandleImpl :: CloneableHandleD (GenericCloneableHandle h) | |
class Handle h => GCloneableHandle (h :: Effects -> Type) #
Minimal complete definition
gCloneableHandleImpl
Instances
| CloneableHandle h => GCloneableHandle (Rec1 h) | |
Defined in Bluefin.Internal.CloneableHandle Methods gCloneableHandleImpl :: CloneableHandleD (Rec1 h) | |
| (GCloneableHandle h1, GCloneableHandle h2) => GCloneableHandle (h1 :*: h2) | |
Defined in Bluefin.Internal.CloneableHandle Methods gCloneableHandleImpl :: CloneableHandleD (h1 :*: h2) | |
| GCloneableHandle h => GCloneableHandle (M1 i t h) | |
Defined in Bluefin.Internal.CloneableHandle Methods gCloneableHandleImpl :: CloneableHandleD (M1 i t h) | |
GHC.Generics re-exports
class Generic1 (f :: k -> Type) #
Minimal complete definition
from1, to1
Instances
| Generic1 Down | |
Defined in GHC.Generics Associated Types type Rep1 Down :: k -> Type | |
| Generic1 NonEmpty | |
Defined in GHC.Generics Associated Types type Rep1 NonEmpty :: k -> Type | |
| Generic1 Par1 | |
Defined in GHC.Generics Associated Types type Rep1 Par1 :: k -> Type | |
| Generic1 Maybe | |
Defined in GHC.Generics Associated Types type Rep1 Maybe :: k -> Type | |
| Generic1 Solo | |
Defined in GHC.Generics Associated Types type Rep1 Solo :: k -> Type | |
| Generic1 List | |
Defined in GHC.Generics Associated Types type Rep1 List :: k -> Type | |
| Generic1 (Either a :: Type -> Type) | |
Defined in GHC.Generics Associated Types type Rep1 (Either a) :: k -> Type | |
| Generic1 ((,) a :: Type -> Type) | |
Defined in GHC.Generics Associated Types type Rep1 ((,) a) :: k -> Type | |
| Generic1 (Proxy :: k -> Type) | |
Defined in GHC.Generics Associated Types type Rep1 Proxy :: k -> Type | |
| Generic1 (U1 :: k -> Type) | |
Defined in GHC.Generics Associated Types type Rep1 U1 :: k -> Type | |
| Generic1 (V1 :: k -> Type) | |
Defined in GHC.Generics Associated Types type Rep1 V1 :: k -> Type | |
| Generic1 ((,,) a b :: Type -> Type) | |
Defined in GHC.Generics Associated Types type Rep1 ((,,) a b) :: k -> Type | |
| Generic1 (Rec1 f :: k -> Type) | |
Defined in GHC.Generics Associated Types type Rep1 (Rec1 f) :: k -> Type | |
| Generic1 (URec (Ptr ()) :: k -> Type) | |
Defined in GHC.Generics Associated Types type Rep1 (URec (Ptr ())) :: k -> Type | |
| Generic1 (URec Char :: k -> Type) | |
Defined in GHC.Generics Associated Types type Rep1 (URec Char) :: k -> Type | |
| Generic1 (URec Double :: k -> Type) | |
Defined in GHC.Generics Associated Types type Rep1 (URec Double) :: k -> Type | |
| Generic1 (URec Float :: k -> Type) | |
Defined in GHC.Generics Associated Types type Rep1 (URec Float) :: k -> Type | |
| Generic1 (URec Int :: k -> Type) | |
Defined in GHC.Generics Associated Types type Rep1 (URec Int) :: k -> Type | |
| Generic1 (URec Word :: k -> Type) | |
Defined in GHC.Generics Associated Types type Rep1 (URec Word) :: k -> Type | |
| Generic1 ((,,,) a b c :: Type -> Type) | |
Defined in GHC.Generics Associated Types type Rep1 ((,,,) a b c) :: k -> Type | |
| Generic1 (f :*: g :: k -> Type) | |
Defined in GHC.Generics Associated Types type Rep1 (f :*: g) :: k -> Type | |
| Generic1 (f :+: g :: k -> Type) | |
Defined in GHC.Generics Associated Types type Rep1 (f :+: g) :: k -> Type | |
| Generic1 (K1 i c :: k -> Type) | |
Defined in GHC.Generics Associated Types type Rep1 (K1 i c) :: k -> Type | |
| Generic1 ((,,,,) a b c d :: Type -> Type) | |
Defined in GHC.Generics Associated Types type Rep1 ((,,,,) a b c d) :: k -> Type | |
| Functor f => Generic1 (f :.: g :: k -> Type) | |
Defined in GHC.Generics Associated Types type Rep1 (f :.: g) :: k -> Type | |
| Generic1 (M1 i c f :: k -> Type) | |
Defined in GHC.Generics Associated Types type Rep1 (M1 i c f) :: k -> Type | |
| Generic1 ((,,,,,) a b c d e :: Type -> Type) | |
Defined in GHC.Generics Associated Types type Rep1 ((,,,,,) a b c d e) :: k -> Type | |
| Generic1 ((,,,,,,) a b c d e f :: Type -> Type) | |
Defined in GHC.Generics Associated Types type Rep1 ((,,,,,,) a b c d e f) :: k -> Type | |
| Generic1 ((,,,,,,,) a b c d e f g :: Type -> Type) | |
Defined in GHC.Generics Associated Types type Rep1 ((,,,,,,,) a b c d e f g) :: k -> Type | |
| Generic1 ((,,,,,,,,) a b c d e f g h :: Type -> Type) | |
Defined in GHC.Generics Associated Types type Rep1 ((,,,,,,,,) a b c d e f g h) :: k -> Type | |
| Generic1 ((,,,,,,,,,) a b c d e f g h i :: Type -> Type) | |
Defined in GHC.Generics Associated Types type Rep1 ((,,,,,,,,,) a b c d e f g h i) :: k -> Type | |
| Generic1 ((,,,,,,,,,,) a b c d e f g h i j :: Type -> Type) | |
Defined in GHC.Generics Associated Types type Rep1 ((,,,,,,,,,,) a b c d e f g h i j) :: k -> Type | |
| Generic1 ((,,,,,,,,,,,) a b c d e f g h i j k :: Type -> Type) | |
Defined in GHC.Generics Associated Types type Rep1 ((,,,,,,,,,,,) a b c d e f g h i j k) :: k -> Type | |
| Generic1 ((,,,,,,,,,,,,) a b c d e f g h i j k l :: Type -> Type) | |
Defined in GHC.Generics Associated Types type Rep1 ((,,,,,,,,,,,,) a b c d e f g h i j k l) :: k -> Type | |
| Generic1 ((,,,,,,,,,,,,,) a b c d e f g h i j k l m :: Type -> Type) | |
Defined in GHC.Generics Associated Types type Rep1 ((,,,,,,,,,,,,,) a b c d e f g h i j k l m) :: k -> Type | |
| Generic1 ((,,,,,,,,,,,,,,) a b c d e f g h i j k l m n :: Type -> Type) | |
Defined in GHC.Generics Associated Types type Rep1 ((,,,,,,,,,,,,,,) a b c d e f g h i j k l m n) :: k -> Type | |