mirror of
https://github.com/tomjaguarpaw/bluefin.git
synced 2024-10-04 01:17:52 +03:00
Some docs
This commit is contained in:
parent
97cd74b199
commit
caa59700d9
@ -12,66 +12,28 @@ import Effectful.Internal.Env
|
||||
import qualified Effectful.Internal.Monad as Effectful
|
||||
import qualified Effectful.State.Dynamic as St
|
||||
|
||||
newtype Effectful es (e :: Effects) = MkEffectful (Env es)
|
||||
-- * Bluefin handle
|
||||
|
||||
-- | Provide access to Effectful operations in Bluefin
|
||||
newtype Effectful (es' :: [EffectfulEffect]) (e :: Effects)
|
||||
= MkEffectful (Env es')
|
||||
|
||||
-- * Effectful effect
|
||||
|
||||
-- | Provide access to Bluefin operations in Effectful
|
||||
data Bluefin es m a
|
||||
|
||||
-- * Type synonyms
|
||||
|
||||
type instance DispatchOf (Bluefin es) = Dynamic
|
||||
|
||||
voidBluefin :: Bluefin es m a -> r
|
||||
voidBluefin = \case {}
|
||||
type EffectfulEff = Effectful.Eff
|
||||
|
||||
useEffectful ::
|
||||
(e :> es) =>
|
||||
-- | Bluefin handle to @effectful@ operations
|
||||
Effectful effes e ->
|
||||
-- | An @effectful@ operation
|
||||
Effectful.Eff effes r ->
|
||||
Eff es r
|
||||
useEffectful e k =
|
||||
fromEffectful (\Proxy -> Effectful.inject k) e
|
||||
type EffectfulEffect = Effectful.Effect
|
||||
|
||||
useBluefin ::
|
||||
forall es effes r.
|
||||
(Bluefin es Effectful.:> effes) =>
|
||||
Eff es r ->
|
||||
Effectful.Eff effes r
|
||||
useBluefin m =
|
||||
toEffectful (\(_ :: Effectful effes e) -> useImpl @es @(e :& es) m)
|
||||
type a ::> b = a Effectful.:> b
|
||||
|
||||
toEffectful ::
|
||||
forall es effes a.
|
||||
(Bluefin es Effectful.:> effes) =>
|
||||
(forall e. Effectful effes e -> Eff (e :& es) a) ->
|
||||
Effectful.Eff effes a
|
||||
toEffectful = unsafeToEffectful
|
||||
|
||||
unsafeInterpretBluefin ::
|
||||
Effectful.Eff (Bluefin es : effes) a -> Effectful.Eff effes a
|
||||
unsafeInterpretBluefin = Effectful.interpret (\_ -> voidBluefin)
|
||||
|
||||
fromEffectful ::
|
||||
(e :> es) =>
|
||||
(Proxy es -> Effectful.Eff (Bluefin es : effes) r) ->
|
||||
Effectful effes e ->
|
||||
Eff es r
|
||||
fromEffectful m (MkEffectful env) =
|
||||
UnsafeMkEff (Effectful.unEff (unsafeInterpretBluefin (m Proxy)) env)
|
||||
|
||||
unsafeToEffectful :: (Effectful es e -> Eff es' a) -> Effectful.Eff es a
|
||||
unsafeToEffectful m =
|
||||
Effectful.unsafeEff (\env' -> unsafeUnEff (m (MkEffectful env')))
|
||||
|
||||
handleWith ::
|
||||
(e1 :> es) =>
|
||||
-- | An @effectful@ handler
|
||||
(Effectful.Eff (effe : effes) r1 -> Effectful.Eff effes r2) ->
|
||||
-- | An @effectful@ operation, in Bluefin style
|
||||
(forall e. Effectful (effe : effes) e -> Eff (e :& es) r1) ->
|
||||
Effectful effes e1 ->
|
||||
Eff es r2
|
||||
handleWith handler m (MkEffectful env) =
|
||||
UnsafeMkEff (Effectful.unEff (handler (unsafeToEffectful m)) env)
|
||||
-- * Bluefin handlers
|
||||
|
||||
runEffectful ::
|
||||
(e1 :> es) =>
|
||||
@ -87,26 +49,86 @@ runPureEffectful ::
|
||||
Eff es r
|
||||
runPureEffectful k = pure (Effectful.runPureEff (unsafeToEffectful k))
|
||||
|
||||
handleWith ::
|
||||
(e1 :> es) =>
|
||||
-- | An @effectful@ handler
|
||||
(EffectfulEff (e' : es') r1 -> EffectfulEff es' r2) ->
|
||||
-- | An @effectful@ operation, in Bluefin style
|
||||
(forall e. Effectful (e' : es') e -> Eff (e :& es) r1) ->
|
||||
Effectful es' e1 ->
|
||||
-- | The result of handling the @effectful@ operation in Bluefin
|
||||
-- style using the @effectful@ handler
|
||||
Eff es r2
|
||||
handleWith handler m (MkEffectful env) =
|
||||
UnsafeMkEff (Effectful.unEff (handler (unsafeToEffectful m)) env)
|
||||
|
||||
-- * Effectful handlers
|
||||
|
||||
runBluefin ::
|
||||
Effectful.IOE Effectful.:> effes =>
|
||||
(forall e es. IOE e -> Effectful.Eff (Bluefin (e :& es) : effes) r) ->
|
||||
Effectful.Eff effes r
|
||||
(Effectful.IOE ::> es') =>
|
||||
-- | A Bluefin operation, in Effectful style (with IO)
|
||||
(forall e es. IOE e -> EffectfulEff (Bluefin (e :& es) : es') r) ->
|
||||
EffectfulEff es' r
|
||||
runBluefin m = unsafeInterpretBluefin (m MkIOE)
|
||||
|
||||
runPureBluefin ::
|
||||
(forall es. Effectful.Eff (Bluefin es : effes) r) ->
|
||||
Effectful.Eff effes r
|
||||
-- | A Bluefin operation, in Effectful style (without IO)
|
||||
(forall es. EffectfulEff (Bluefin es : es') r) ->
|
||||
EffectfulEff es' r
|
||||
runPureBluefin = unsafeInterpretBluefin
|
||||
|
||||
-- * Use Bluefin operations in @effectful@ and vice versa
|
||||
|
||||
useEffectful ::
|
||||
(e :> es) =>
|
||||
-- | Bluefin handle to @effectful@ operations
|
||||
Effectful es' e ->
|
||||
-- | An @effectful@ operation
|
||||
EffectfulEff es' r ->
|
||||
Eff es r
|
||||
useEffectful e k =
|
||||
fromEffectful (\Proxy -> Effectful.inject k) e
|
||||
|
||||
useBluefin ::
|
||||
forall es es' r.
|
||||
(Bluefin es ::> es') =>
|
||||
Eff es r ->
|
||||
-- | ͘
|
||||
EffectfulEff es' r
|
||||
useBluefin m =
|
||||
toEffectful (\(_ :: Effectful es' e) -> useImpl @es @(e :& es) m)
|
||||
|
||||
-- * Conversion between @effectful@ and Bluefin
|
||||
|
||||
toEffectful ::
|
||||
forall (es :: Effects) (es' :: [EffectfulEffect]) a.
|
||||
(Bluefin es ::> es') =>
|
||||
(forall e. Effectful es' e -> Eff (e :& es) a) ->
|
||||
-- | ͘
|
||||
EffectfulEff es' a
|
||||
toEffectful = unsafeToEffectful
|
||||
|
||||
fromEffectful ::
|
||||
(e :> es) =>
|
||||
(Proxy es -> EffectfulEff (Bluefin es : es') r) ->
|
||||
Effectful es' e ->
|
||||
-- | ͘
|
||||
Eff es r
|
||||
fromEffectful m (MkEffectful env) =
|
||||
UnsafeMkEff (Effectful.unEff (unsafeInterpretBluefin (m Proxy)) env)
|
||||
|
||||
-- * Example code
|
||||
|
||||
example ::
|
||||
( St.State Int Effectful.:> es,
|
||||
Er.Error String Effectful.:> es,
|
||||
Bluefin bes Effectful.:> es,
|
||||
e :> bes
|
||||
( St.State Int ::> es',
|
||||
Er.Error String ::> es',
|
||||
Bluefin es ::> es',
|
||||
e :> es
|
||||
) =>
|
||||
State Int e ->
|
||||
Proxy bes ->
|
||||
Effectful.Eff es Int
|
||||
Proxy es ->
|
||||
-- | ͘
|
||||
EffectfulEff es' Int
|
||||
example bst (_ :: Proxy bes) = do
|
||||
r <- St.get
|
||||
St.put (r + 1 :: Int)
|
||||
@ -116,14 +138,15 @@ example bst (_ :: Proxy bes) = do
|
||||
St.get
|
||||
|
||||
bfExample ::
|
||||
forall e es e1 effes.
|
||||
forall e es e1 es'.
|
||||
( e :> es,
|
||||
e1 :> es,
|
||||
St.State Int Effectful.:> effes,
|
||||
Er.Error String Effectful.:> effes
|
||||
St.State Int ::> es',
|
||||
Er.Error String ::> es'
|
||||
) =>
|
||||
State Int e1 ->
|
||||
Effectful effes e ->
|
||||
Effectful es' e ->
|
||||
-- | ͘
|
||||
Eff es Int
|
||||
bfExample s e = do
|
||||
r <- fromEffectful (\_ -> example s (Proxy @es)) e
|
||||
@ -146,3 +169,16 @@ runExample i =
|
||||
-- Right 10
|
||||
-- > runExample 10
|
||||
-- Left "foo"
|
||||
|
||||
-- * Unsafe internals
|
||||
|
||||
voidBluefin :: Bluefin es m a -> r
|
||||
voidBluefin = \case {}
|
||||
|
||||
unsafeInterpretBluefin ::
|
||||
EffectfulEff (Bluefin es : es') a -> EffectfulEff es' a
|
||||
unsafeInterpretBluefin = Effectful.interpret (\_ -> voidBluefin)
|
||||
|
||||
unsafeToEffectful :: (Effectful es e -> Eff es' a) -> EffectfulEff es a
|
||||
unsafeToEffectful m =
|
||||
Effectful.unsafeEff (\env' -> unsafeUnEff (m (MkEffectful env')))
|
||||
|
Loading…
Reference in New Issue
Block a user