-- | For defining @PrimMonad@ instances, for example: -- -- @ -- -- Define a handle which includes Prim -- data ExAndPrim e = MkExAndPrim (Exception String e) (P.Prim e) -- -- Give it a Handle instance, as per Bluefin.Compound -- deriving (Handle) via OneWayCoercibleHandle ExAndPrim -- deriving stock (Generic) -- -- instance (e :> es) => OneWayCoercible (ExAndPrim e) (ExAndPrim es) where -- oneWayCoercibleImpl = gOneWayCoercible -- -- -- Define a monad M containing the Prim handle -- newtype M e es a = MkM (ReaderT (ExAndPrim e) (Eff es) a) -- deriving newtype (Functor, Applicative, Monad) -- -- -- Define a way of running M -- runM :: -- (e1 :> es, e2 :> es) => -- Exception String e1 -> -- P.Prim e2 -> -- M es es r -> -- Eff es r -- runM ex prim (MkM m) = -- runReaderT m (MkExAndPrim (mapHandle ex) (mapHandle prim)) -- -- -- Give M a PrimMonad instance -- instance (e :> es) => PrimMonad (M e es) where -- type PrimState (M e es) = P.PrimStateEff e -- primitive f = -- MkM (ReaderT (\\(MkExAndPrim _ prim) -> P.'primitive' prim f)) -- -- -- ghci> example -- -- Right [\"Hello\",\"World\"] -- example :: Either String [String] -- example = runPureEff $ try $ \\ex -> P.'runPrim' $ \\prim -> do -- runM ex prim $ do -- arr <- A.newArray 2 \"Hello\" -- A.writeArray arr 1 \"World\" -- for [0, 1] (A.readArray arr) -- @ module Bluefin.Prim (Prim, runPrim, PrimStateEff, primitive) where import Bluefin.Internal.Prim