packages feed

bluefin-internal 0.7.0.0 → 0.8.0.0

raw patch · 5 files changed

+18/−1116 lines, 5 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

- Bluefin.Internal: mapStream :: forall (e2 :: Effects) (es :: Effects) a b r. e2 <: es => (a -> b) -> (forall (e1 :: Effects). () => Stream a e1 -> Eff (e1 :& es) r) -> Stream b e2 -> Eff es r
- Bluefin.Internal: zipCoroutines :: forall (e1 :: Effects) (es :: Effects) a1 a2 b r. e1 <: es => Coroutine (a1, a2) b e1 -> (forall (e :: Effects). () => Coroutine a1 b e -> Eff (e :& es) r) -> (forall (e :: Effects). () => Coroutine a2 b e -> Eff (e :& es) r) -> Eff es r
- Bluefin.Internal.Examples: DynamicReader :: Eff e r -> (forall (e' :: Effects) a. () => (r -> r) -> Eff e' a -> Eff (e' :& e) a) -> DynamicReader r (e :: Effects)
- Bluefin.Internal.Examples: MkApplication :: (String -> Int -> Eff e [String]) -> Modify (Int, Bool) e -> Stream String e -> Application (e :: Effects)
- Bluefin.Internal.Examples: MkCounter1 :: Modify Int e -> Counter1 (e :: Effects)
- Bluefin.Internal.Examples: MkCounter2 :: Modify Int e1 -> Throw () e2 -> Counter2 (e1 :: Effects) (e2 :: Effects)
- Bluefin.Internal.Examples: MkCounter3 :: Modify Int e -> Throw () e -> Counter3 (e :: Effects)
- Bluefin.Internal.Examples: MkCounter3B :: IOE e -> Counter3B (e :: Effects)
- Bluefin.Internal.Examples: MkCounter4 :: Modify Int e -> Throw () e -> Stream String e -> Counter4 (e :: Effects)
- Bluefin.Internal.Examples: MkCounter5 :: Eff e () -> (String -> Eff e Int) -> Counter5 (e :: Effects)
- Bluefin.Internal.Examples: MkCounter6 :: Eff e () -> Modify Int e -> Stream String e -> Counter6 (e :: Effects)
- Bluefin.Internal.Examples: MkCounter7 :: (forall (e' :: Effects). () => Throw () e' -> Eff (e' :& e) ()) -> Modify Int e -> Stream String e -> Counter7 (e :: Effects)
- Bluefin.Internal.Examples: MkFileSystem :: (FilePath -> Eff es String) -> (FilePath -> String -> Eff es ()) -> FileSystem (es :: Effects)
- Bluefin.Internal.Examples: [applicationModify] :: Application (e :: Effects) -> Modify (Int, Bool) e
- Bluefin.Internal.Examples: [askLRImpl] :: DynamicReader r (e :: Effects) -> Eff e r
- Bluefin.Internal.Examples: [counter6Modify] :: Counter6 (e :: Effects) -> Modify Int e
- Bluefin.Internal.Examples: [counter6Stream] :: Counter6 (e :: Effects) -> Stream String e
- Bluefin.Internal.Examples: [counter7Modify] :: Counter7 (e :: Effects) -> Modify Int e
- Bluefin.Internal.Examples: [counter7Stream] :: Counter7 (e :: Effects) -> Stream String e
- Bluefin.Internal.Examples: [getCounter5Impl] :: Counter5 (e :: Effects) -> String -> Eff e Int
- Bluefin.Internal.Examples: [incCounter5Impl] :: Counter5 (e :: Effects) -> Eff e ()
- Bluefin.Internal.Examples: [incCounter6Impl] :: Counter6 (e :: Effects) -> Eff e ()
- Bluefin.Internal.Examples: [incCounter7Impl] :: Counter7 (e :: Effects) -> forall (e' :: Effects). () => Throw () e' -> Eff (e' :& e) ()
- Bluefin.Internal.Examples: [localLRImpl] :: DynamicReader r (e :: Effects) -> forall (e' :: Effects) a. () => (r -> r) -> Eff e' a -> Eff (e' :& e) a
- Bluefin.Internal.Examples: [logger] :: Application (e :: Effects) -> Stream String e
- Bluefin.Internal.Examples: [queryDatabase] :: Application (e :: Effects) -> String -> Int -> Eff e [String]
- Bluefin.Internal.Examples: [readFileImpl] :: FileSystem (es :: Effects) -> FilePath -> Eff es String
- Bluefin.Internal.Examples: [writeFileImpl] :: FileSystem (es :: Effects) -> FilePath -> String -> Eff es ()
- Bluefin.Internal.Examples: action :: forall (e :: Effects) (es :: Effects). e <: es => FileSystem e -> Eff es String
- Bluefin.Internal.Examples: askLR :: forall (e :: Effects) (es :: Effects) r. e <: es => DynamicReader r e -> Eff es r
- Bluefin.Internal.Examples: awaitExample :: IO ()
- Bluefin.Internal.Examples: awaitList :: forall (e :: Effects) (es :: Effects) a. e <: es => [a] -> IOE e -> (forall (e1 :: Effects). () => Consume a e1 -> Eff (e1 :& es) ()) -> Eff es ()
- Bluefin.Internal.Examples: awaitUsage :: forall (e1 :: Effects) (es :: Effects) (e2 :: Effects). (e1 <: es, e2 <: es) => IOE e1 -> (forall (e :: Effects). () => Consume () e -> Eff (e :& es) ()) -> Consume Int e2 -> Eff es ()
- Bluefin.Internal.Examples: compoundExample :: Either String (a, Int)
- Bluefin.Internal.Examples: connectExample :: IO (Either String String)
- Bluefin.Internal.Examples: consumeStreamExample :: IO (Either String String)
- Bluefin.Internal.Examples: consumeStreamExample2 :: IO ()
- Bluefin.Internal.Examples: countExample :: IO ()
- Bluefin.Internal.Examples: countPositivesNegatives :: [Int] -> String
- Bluefin.Internal.Examples: cycleToStreamExample :: ([Int], ())
- Bluefin.Internal.Examples: data Application (e :: Effects)
- Bluefin.Internal.Examples: data Counter2 (e1 :: Effects) (e2 :: Effects)
- Bluefin.Internal.Examples: data Counter3 (e :: Effects)
- Bluefin.Internal.Examples: data Counter4 (e :: Effects)
- Bluefin.Internal.Examples: data Counter5 (e :: Effects)
- Bluefin.Internal.Examples: data Counter6 (e :: Effects)
- Bluefin.Internal.Examples: data Counter7 (e :: Effects)
- Bluefin.Internal.Examples: data DynamicReader r (e :: Effects)
- Bluefin.Internal.Examples: data FileSystem (es :: Effects)
- Bluefin.Internal.Examples: doubleNestedForEach :: forall (es :: Effects). (forall (e :: Effects). () => Stream () e -> Eff (e :& es) ()) -> Eff es ()
- Bluefin.Internal.Examples: effIOExample :: IO ()
- Bluefin.Internal.Examples: enumerateExample :: ([(Int, String)], ())
- Bluefin.Internal.Examples: example1_ :: (Int, Int)
- Bluefin.Internal.Examples: example2_ :: ((Int, Int), (Int, Int))
- Bluefin.Internal.Examples: example3' :: Int -> Either String Int
- Bluefin.Internal.Examples: example3_ :: IO ()
- Bluefin.Internal.Examples: exampleCounter1 :: Int
- Bluefin.Internal.Examples: exampleCounter2 :: Int
- Bluefin.Internal.Examples: exampleCounter3 :: Int
- Bluefin.Internal.Examples: exampleCounter3B :: IO ()
- Bluefin.Internal.Examples: exampleCounter4 :: ([String], Int)
- Bluefin.Internal.Examples: exampleCounter5 :: ([String], Int)
- Bluefin.Internal.Examples: exampleCounter6 :: ([String], Int)
- Bluefin.Internal.Examples: exampleCounter7A :: ([String], Int)
- Bluefin.Internal.Examples: exampleCounter7B :: ([String], Int)
- Bluefin.Internal.Examples: exampleGet :: (Int, Int)
- Bluefin.Internal.Examples: exampleModify :: ((), Int)
- Bluefin.Internal.Examples: examplePut :: ((), Int)
- Bluefin.Internal.Examples: exampleRunFileSystemIO :: IO (Either String String)
- Bluefin.Internal.Examples: exampleRunFileSystemPure :: Either String String
- Bluefin.Internal.Examples: forEachExample :: ([Int], ())
- Bluefin.Internal.Examples: getCounter4 :: forall (e :: Effects) (es :: Effects). e <: es => Counter4 e -> String -> Eff es Int
- Bluefin.Internal.Examples: getCounter5 :: forall (e :: Effects) (es :: Effects). e <: es => Counter5 e -> String -> Eff es Int
- Bluefin.Internal.Examples: getCounter6 :: forall (e :: Effects) (es :: Effects). e <: es => Counter6 e -> String -> Eff es Int
- Bluefin.Internal.Examples: getCounter7 :: forall (e :: Effects) (es :: Effects). e <: es => Counter7 e -> String -> Eff es Int
- Bluefin.Internal.Examples: handleExample :: String
- Bluefin.Internal.Examples: ignoreStreamExample :: Int
- Bluefin.Internal.Examples: inFoldableExample :: ([Int], ())
- Bluefin.Internal.Examples: incCounter1 :: forall (e :: Effects) (es :: Effects). e <: es => Counter1 e -> Eff es ()
- Bluefin.Internal.Examples: incCounter2 :: forall (e1 :: Effects) (es :: Effects) (e2 :: Effects). (e1 <: es, e2 <: es) => Counter2 e1 e2 -> Eff es ()
- Bluefin.Internal.Examples: incCounter3 :: forall (e :: Effects) (es :: Effects). e <: es => Counter3 e -> Eff es ()
- Bluefin.Internal.Examples: incCounter3B :: forall (e :: Effects) (es :: Effects). e <: es => Counter3B e -> Eff es ()
- Bluefin.Internal.Examples: incCounter4 :: forall (e :: Effects) (es :: Effects). e <: es => Counter4 e -> Eff es ()
- Bluefin.Internal.Examples: incCounter5 :: forall (e :: Effects) (es :: Effects). e <: es => Counter5 e -> Eff es ()
- Bluefin.Internal.Examples: incCounter6 :: forall (e :: Effects) (es :: Effects). e <: es => Counter6 e -> Eff es ()
- Bluefin.Internal.Examples: incCounter7 :: forall (e :: Effects) (es :: Effects) (e1 :: Effects). (e <: es, e1 <: es) => Counter7 e -> Throw () e1 -> Eff es ()
- Bluefin.Internal.Examples: incrementReadLine :: forall (e1 :: Effects) (es :: Effects) (e2 :: Effects) (e3 :: Effects). (e1 <: es, e2 <: es, e3 <: es) => Modify Int e1 -> Throw String e2 -> IOE e3 -> Eff es ()
- Bluefin.Internal.Examples: instance (e Bluefin.Internal.<: es) => Bluefin.Internal.OneWayCoercible.OneWayCoercible (Bluefin.Internal.Examples.Application e) (Bluefin.Internal.Examples.Application es)
- Bluefin.Internal.Examples: instance (e Bluefin.Internal.<: es) => Bluefin.Internal.OneWayCoercible.OneWayCoercible (Bluefin.Internal.Examples.Counter5 e) (Bluefin.Internal.Examples.Counter5 es)
- Bluefin.Internal.Examples: instance (e Bluefin.Internal.<: es) => Bluefin.Internal.OneWayCoercible.OneWayCoercible (Bluefin.Internal.Examples.Counter6 e) (Bluefin.Internal.Examples.Counter6 es)
- Bluefin.Internal.Examples: instance (e Bluefin.Internal.<: es) => Bluefin.Internal.OneWayCoercible.OneWayCoercible (Bluefin.Internal.Examples.Counter7 e) (Bluefin.Internal.Examples.Counter7 es)
- Bluefin.Internal.Examples: instance (e Bluefin.Internal.<: es) => Bluefin.Internal.OneWayCoercible.OneWayCoercible (Bluefin.Internal.Examples.DynamicReader r e) (Bluefin.Internal.Examples.DynamicReader r es)
- Bluefin.Internal.Examples: instance (e Bluefin.Internal.<: es) => Bluefin.Internal.OneWayCoercible.OneWayCoercible (Bluefin.Internal.Examples.FileSystem e) (Bluefin.Internal.Examples.FileSystem es)
- Bluefin.Internal.Examples: instance Bluefin.Internal.Handle (Bluefin.Internal.Examples.DynamicReader r)
- Bluefin.Internal.Examples: instance Bluefin.Internal.Handle Bluefin.Internal.Examples.Application
- Bluefin.Internal.Examples: instance Bluefin.Internal.Handle Bluefin.Internal.Examples.Counter5
- Bluefin.Internal.Examples: instance Bluefin.Internal.Handle Bluefin.Internal.Examples.Counter6
- Bluefin.Internal.Examples: instance Bluefin.Internal.Handle Bluefin.Internal.Examples.Counter7
- Bluefin.Internal.Examples: instance Bluefin.Internal.Handle Bluefin.Internal.Examples.FileSystem
- Bluefin.Internal.Examples: instance GHC.Generics.Generic (Bluefin.Internal.Examples.Application e)
- Bluefin.Internal.Examples: instance GHC.Generics.Generic (Bluefin.Internal.Examples.Counter5 e)
- Bluefin.Internal.Examples: instance GHC.Generics.Generic (Bluefin.Internal.Examples.Counter6 e)
- Bluefin.Internal.Examples: instance GHC.Generics.Generic (Bluefin.Internal.Examples.FileSystem es)
- Bluefin.Internal.Examples: localLR :: forall (e :: Effects) (es :: Effects) r a. e <: es => DynamicReader r e -> (r -> r) -> Eff es a -> Eff es a
- Bluefin.Internal.Examples: mapRec :: forall (e :: Effects) (es :: Effects) a b. e <: es => (a -> b) -> (forall (e1 :: Effects). () => Consume b e1 -> Eff (e1 :& es) ()) -> Consume a e -> Eff es ()
- Bluefin.Internal.Examples: monadFailExample :: Either String ()
- Bluefin.Internal.Examples: monadIOExample :: IO ()
- Bluefin.Internal.Examples: myBail :: forall (e :: Effects) (es :: Effects) r. e <: es => MyHandle e -> Eff es r
- Bluefin.Internal.Examples: myInc :: forall (e :: Effects) (es :: Effects). e <: es => MyHandle e -> Eff es ()
- Bluefin.Internal.Examples: newtype Counter1 (e :: Effects)
- Bluefin.Internal.Examples: newtype Counter3B (e :: Effects)
- Bluefin.Internal.Examples: pipesExample1 :: IO ()
- Bluefin.Internal.Examples: pipesExample2 :: IO String
- Bluefin.Internal.Examples: polymorphicBracket :: forall (st :: Effects) (es :: Effects). st <: es => Modify (Integer, Bool) st -> Eff es () -> Eff es ()
- Bluefin.Internal.Examples: polymorphicBracketExample1 :: (Integer, Bool)
- Bluefin.Internal.Examples: polymorphicBracketExample2 :: (Integer, Bool)
- Bluefin.Internal.Examples: promptCoroutine :: IO ()
- Bluefin.Internal.Examples: readFile :: forall (e :: Effects) (es :: Effects). e <: es => FileSystem e -> FilePath -> Eff es String
- Bluefin.Internal.Examples: rethrowIOExample :: IO ()
- Bluefin.Internal.Examples: returnEarlyExample :: String
- Bluefin.Internal.Examples: runCounter1 :: forall (es :: Effects) r. (forall (e :: Effects). () => Counter1 e -> Eff (e :& es) r) -> Eff es Int
- Bluefin.Internal.Examples: runCounter2 :: forall (es :: Effects) r. (forall (e1 :: Effects) (e2 :: Effects). () => Counter2 e1 e2 -> Eff (e2 :& (e1 :& es)) r) -> Eff es Int
- Bluefin.Internal.Examples: runCounter3 :: forall (es :: Effects) r. (forall (e :: Effects). () => Counter3 e -> Eff (e :& es) r) -> Eff es Int
- Bluefin.Internal.Examples: runCounter3B :: forall (e1 :: Effects) (es :: Effects) r. e1 <: es => IOE e1 -> (forall (e :: Effects). () => Counter3B e -> Eff (e :& es) r) -> Eff es r
- Bluefin.Internal.Examples: runCounter4 :: forall (e1 :: Effects) (es :: Effects) r. e1 <: es => Stream String e1 -> (forall (e :: Effects). () => Counter4 e -> Eff (e :& es) r) -> Eff es Int
- Bluefin.Internal.Examples: runCounter5 :: forall (e1 :: Effects) (es :: Effects) r. e1 <: es => Stream String e1 -> (forall (e :: Effects). () => Counter5 e -> Eff (e :& es) r) -> Eff es Int
- Bluefin.Internal.Examples: runCounter6 :: forall (e1 :: Effects) (es :: Effects) r. e1 <: es => Stream String e1 -> (forall (e :: Effects). () => Counter6 e -> Eff (e :& es) r) -> Eff es Int
- Bluefin.Internal.Examples: runCounter7 :: forall (e1 :: Effects) (es :: Effects) r. e1 <: es => Stream String e1 -> (forall (e :: Effects). () => Counter7 e -> Eff (e :& es) r) -> Eff es Int
- Bluefin.Internal.Examples: runDynamicReader :: forall r (es :: Effects) a. r -> (forall (e :: Effects). () => DynamicReader r e -> Eff (e :& es) a) -> Eff es a
- Bluefin.Internal.Examples: runFileSystemIO :: forall (e1 :: Effects) (e2 :: Effects) (es :: Effects) r. (e1 <: es, e2 <: es) => Throw String e1 -> IOE e2 -> (forall (e :: Effects). () => FileSystem e -> Eff (e :& es) r) -> Eff es r
- Bluefin.Internal.Examples: runFileSystemPure :: forall (e1 :: Effects) (es :: Effects) r. e1 <: es => Throw String e1 -> [(FilePath, String)] -> (forall (e2 :: Effects). () => FileSystem e2 -> Eff (e2 :& es) r) -> Eff es r
- Bluefin.Internal.Examples: runIncrementReadLine :: IO (Either String Int)
- Bluefin.Internal.Examples: runMyHandle :: forall (es :: Effects) a. (forall (e :: Effects). () => MyHandle e -> Eff (e :& es) a) -> Eff es (Either String (a, Int))
- Bluefin.Internal.Examples: stateSourceExample :: Int
- Bluefin.Internal.Examples: takeConsumeExample :: ([Int], ())
- Bluefin.Internal.Examples: takeRec :: forall (e3 :: Effects) (es :: Effects) a. e3 <: es => Int -> (forall (e :: Effects). () => Consume a e -> Eff (e :& es) ()) -> Consume a e3 -> Eff es ()
- Bluefin.Internal.Examples: throwExample :: Either Int String
- Bluefin.Internal.Examples: traverseRec :: forall (e :: Effects) (es :: Effects) a b. e <: es => (a -> Eff es b) -> (forall (e1 :: Effects). () => Consume b e1 -> Eff (e1 :& es) ()) -> Consume a e -> Eff es ()
- Bluefin.Internal.Examples: type MyHandle = Compound Modify Int Throw String
- Bluefin.Internal.Examples: while :: forall (es :: Effects) a. Eff es Bool -> Eff es a -> Eff es ()
- Bluefin.Internal.Examples: withYieldToListExample :: Int
- Bluefin.Internal.Examples: writeFile :: forall (e :: Effects) (es :: Effects). e <: es => FileSystem e -> FilePath -> String -> Eff es ()
- Bluefin.Internal.Examples: writerExample1 :: Bool
- Bluefin.Internal.Examples: writerExample2 :: Bool
- Bluefin.Internal.Examples: yieldExample :: ([Int], ())
- Bluefin.Internal.Examples: zipCoroutinesExample :: IO ()
- Bluefin.Internal: MkReader :: Key r -> Reader r (e :: k)
+ Bluefin.Internal: MkReader :: Key r -> Reader r (e :: Effects)
- Bluefin.Internal: UnsafeMkHandleReader :: Reader (h e) e -> HandleReader (h :: k -> Type) (e :: k)
+ Bluefin.Internal: UnsafeMkHandleReader :: Reader (h e) e -> HandleReader (h :: Effects -> Type) (e :: Effects)
- Bluefin.Internal: newtype HandleReader (h :: k -> Type) (e :: k)
+ Bluefin.Internal: newtype HandleReader (h :: Effects -> Type) (e :: Effects)
- Bluefin.Internal: newtype Reader r (e :: k)
+ Bluefin.Internal: newtype Reader r (e :: Effects)
- Bluefin.Internal: type Ask = Reader :: Type -> k -> Type
+ Bluefin.Internal: type Ask = Reader
- Bluefin.Internal: type AskCapability = HandleReader :: k -> Type -> k -> Type
+ Bluefin.Internal: type AskCapability = HandleReader
- Bluefin.Internal.CloneableHandle: hcReader :: forall r (e :: Effects). HandleCloner (Reader r :: Effects -> Type) (Reader r :: Effects -> Type) e
+ Bluefin.Internal.CloneableHandle: hcReader :: forall r (e :: Effects). HandleCloner (Reader r) (Reader r) e

Files

CHANGELOG.md view
@@ -1,3 +1,10 @@+# 0.8.0.0++* Restrict `Reader` type tag to `Effects`++* Move most of `Bluefin.Internal.Examples`, `zipCoroutines` and+  `mapStream` to `Bluefin.Examples`+ # 0.7.0.0  * Fix `Reader` bug that caused incorrect scoping in
bluefin-internal.cabal view
@@ -1,6 +1,6 @@ cabal-version:      3.0 name:               bluefin-internal-version:            0.7.0.0+version:            0.8.0.0 license:            MIT license-file:       LICENSE author:             Tom Ellis@@ -83,7 +83,7 @@       transformers < 0.7,       transformers-base < 0.5,       monad-control < 1.1,-      vault >= 0.3+      vault >= 0.3 && < 0.4     exposed-modules:       Bluefin.Internal,       Bluefin.Internal.CloneableHandle,
src/Bluefin/Internal.hs view
@@ -217,24 +217,6 @@   Eff es r streamConsume s c = consumeStream c s -zipCoroutines ::-  (e1 <: es) =>-  Coroutine (a1, a2) b e1 ->-  (forall e. Coroutine a1 b e -> Eff (e :& es) r) ->-  (forall e. Coroutine a2 b e -> Eff (e :& es) r) ->-  -- | ͘-  Eff es r-zipCoroutines c m1 m2 = do-  connectCoroutines m1 $ \a1 c1 -> do-    connectCoroutines (useImplUnder . m2) $ \a2 c2 -> do-      evalState (a1, a2) $ \ass -> do-        forever $ do-          as <- get ass-          b' <- yieldCoroutine c as-          a1' <- yieldCoroutine c1 b'-          a2' <- yieldCoroutine c2 b'-          put ass (a1', a2')- instance (e <: es) => MonadBase IO (EffReader (IOE e) es) where   liftBase = liftIO @@ -1364,16 +1346,6 @@     as <- get s     pure (as, r) -mapStream ::-  (e2 <: es) =>-  -- | Apply this function to all elements of the input stream.-  (a -> b) ->-  -- | Input stream-  (forall e1. Stream a e1 -> Eff (e1 :& es) r) ->-  Stream b e2 ->-  Eff es r-mapStream f = mapMaybe (Just . f)- mapMaybe ::   (e2 <: es) =>   -- | Yield from the output stream all of the elemnts of the input@@ -1634,6 +1606,8 @@   w ->   Eff es () tell (Writer y) = yield y++type Reader :: Type -> Effects -> Type  newtype Reader r e = MkReader (Vault.Key r)   deriving (Handle) via OneWayCoercibleHandle (Reader r)
src/Bluefin/Internal/Examples.hs view
@@ -1,1086 +1,7 @@-{-# LANGUAGE DerivingVia #-}-{-# LANGUAGE NoMonoLocalBinds #-}-{-# LANGUAGE NoMonomorphismRestriction #-}--module Bluefin.Internal.Examples where--import Bluefin.Internal hiding (b, w)-import Bluefin.Internal.OneWayCoercible-import Bluefin.Internal.Pipes-  ( Producer,-    runEffect,-    stdinLn,-    stdoutLn,-    takeWhile',-    (>->),-  )-import Bluefin.Internal.Pipes qualified as P-import Control.Exception (IOException)-import Control.Exception qualified-import Control.Monad (forever, replicateM_, unless, when)-import Control.Monad.IO.Class (liftIO)-import Data.Foldable (for_)-import Data.Monoid (Any (Any, getAny))-import Data.Proxy (Proxy (Proxy))-import Text.Read (readMaybe)-import Prelude hiding-  ( break,-    drop,-    head,-    read,-    readFile,-    return,-    writeFile,-  )-import Prelude qualified--monadIOExample :: IO ()-monadIOExample = runEff $ \io -> withMonadIO io $ liftIO $ do-  name <- readLn-  putStrLn ("Hello " ++ name)--monadFailExample :: Either String ()-monadFailExample = runPureEff $ try $ \e ->-  when ((2 :: Int) > 1) $-    withMonadFail e (fail "2 was bigger than 1")--throwExample :: Either Int String-throwExample = runPureEff $ try $ \e -> do-  _ <- throw e 42-  pure "No exception thrown"--handleExample :: String-handleExample = runPureEff $ handle (pure . show) $ \e -> do-  _ <- throw e (42 :: Int)-  pure "No exception thrown"--exampleGet :: (Int, Int)-exampleGet = runPureEff $ runModify 10 $ \st -> do-  n <- get st-  pure (2 * n)--examplePut :: ((), Int)-examplePut = runPureEff $ runModify 10 $ \st -> do-  put st 30--exampleModify :: ((), Int)-exampleModify = runPureEff $ runModify 10 $ \st -> do-  modify st (* 2)--yieldExample :: ([Int], ())-yieldExample = runPureEff $ yieldToList $ \y -> do-  yield y 1-  yield y 2-  yield y 100--withYieldToListExample :: Int-withYieldToListExample = runPureEff $ withYieldToList @Int $ \y -> do-  yield y 1-  yield y 2-  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 =-  withModify () $ \_ -> do-    withModify () $ \_ -> do-      forEach (insertManySecond . f) (\_ -> pure ())-      pure (\_ _ -> ())--forEachExample :: ([Int], ())-forEachExample = runPureEff $ yieldToList $ \y -> do-  forEach (inFoldable [0 .. 4]) $ \i -> do-    yield y i-    yield y (i * 10)--ignoreStreamExample :: Int-ignoreStreamExample = runPureEff $ ignoreStream @Int $ \y -> do-  for_ [0 .. 4] $ \i -> do-    yield y i-    yield y (i * 10)--  pure 42---- ([1,2,3,1,2,3],())-cycleToStreamExample :: ([Int], ())-cycleToStreamExample = runPureEff $ yieldToList $ \yOut -> do-  consumeStream-    (\c -> takeConsume 6 c yOut)-    (\yIn -> cycleToStream [1 .. 3] yIn)---- ([1,2,3,4],())-takeConsumeExample :: ([Int], ())-takeConsumeExample = runPureEff $ yieldToList $ \yOut -> do-  consumeStream-    (\c -> takeConsume 4 c yOut)-    (\yIn -> inFoldable [1 .. 10] yIn)--inFoldableExample :: ([Int], ())-inFoldableExample = runPureEff $ yieldToList $ inFoldable [1, 2, 100]--enumerateExample :: ([(Int, String)], ())-enumerateExample = runPureEff $ yieldToList $ enumerate (inFoldable ["A", "B", "C"])--returnEarlyExample :: String-returnEarlyExample = runPureEff $ withEarlyReturn $ \e -> do-  for_ [1 :: Int .. 10] $ \i -> do-    when (i >= 5) $-      returnEarly e ("Returned early with " ++ show i)-  pure "End of loop"--effIOExample :: IO ()-effIOExample = runEff $ \io -> do-  effIO io (putStrLn "Hello world!")--example1_ :: (Int, Int)-example1_ =-  let example1 :: Int -> Int-      example1 n = runPureEff $ evalModify n $ \st -> do-        n' <- get st-        when (n' < 10) $-          put st (n' + 10)-        get st-   in (example1 5, example1 12)--example2_ :: ((Int, Int), (Int, Int))-example2_ =-  let example2 :: (Int, Int) -> (Int, Int)-      example2 (m, n) = runPureEff $-        evalModify m $ \sm -> do-          evalModify n $ \sn -> do-            do-              n' <- get sn-              m' <- get sm--              if n' < m'-                then put sn (n' + 10)-                else put sm (m' + 10)--            n' <- get sn-            m' <- get sm--            pure (n', m')-   in (example2 (5, 10), example2 (12, 5))--example3' :: Int -> Either String Int-example3' n = runPureEff $-  try $ \ex -> do-    evalModify 0 $ \total -> do-      for_ [1 .. n] $ \i -> do-        soFar <- get total-        when (soFar > 20) $ do-          throw ex ("Became too big: " ++ show soFar)-        put total (soFar + i)--      get total---- Count non-empty lines from stdin, and print a friendly message,--- until we see "STOP".-example3_ :: IO ()-example3_ = runEff $ \io -> do-  let getLineUntilStop y = withJump $ \stop -> forever $ do-        line <- effIO io getLine-        when (line == "STOP") $-          jumpTo stop-        yield y line--      nonEmptyLines =-        mapMaybe-          ( \case-              "" -> Nothing-              line -> Just line-          )-          getLineUntilStop--      enumeratedLines = enumerateFrom 1 nonEmptyLines--      formattedLines =-        mapStream-          (\(i, line) -> show i ++ ". Hello! You said " ++ line)-          enumeratedLines--  forEach formattedLines $ \line -> effIO io (putStrLn line)--awaitList ::-  (e <: es) =>-  [a] ->-  IOE e ->-  (forall e1. Consume a e1 -> Eff (e1 :& es) ()) ->-  Eff es ()-awaitList l io k = evalModify l $ \s -> do-  withJump $ \done ->-    bracket-      (pure ())-      (\() -> effIO io (putStrLn "Released"))-      $ \() -> do-        consumeEach (useImplUnder . k) $ do-          (x, xs) <--            get s >>= \case-              [] -> jumpTo done-              x : xs -> pure (x, xs)-          put s xs-          pure x--takeRec ::-  (e3 <: es) =>-  Int ->-  (forall e. Consume a e -> Eff (e :& es) ()) ->-  Consume a e3 ->-  Eff es ()-takeRec n k rec =-  withJump $ \done -> evalModify n $ \s -> consumeEach (useImplUnder . k) $ do-    s' <- get s-    if s' <= 0-      then jumpTo done-      else do-        modify s (subtract 1)-        await rec--mapRec ::-  (e <: es) =>-  (a -> b) ->-  (forall e1. Consume b e1 -> Eff (e1 :& es) ()) ->-  Consume a e ->-  Eff es ()-mapRec f = traverseRec (pure . f)--traverseRec ::-  (e <: es) =>-  (a -> Eff es b) ->-  (forall e1. Consume b e1 -> Eff (e1 :& es) ()) ->-  Consume a e ->-  Eff es ()-traverseRec f k rec = forEach k $ \() -> do-  r <- await rec-  f r--awaitUsage ::-  (e1 <: es, e2 <: es) =>-  IOE e1 ->-  (forall e. Consume () e -> Eff (e :& es) ()) ->-  Consume Int e2 ->-  Eff es ()-awaitUsage io x = do-  mapRec (* 11) $-    mapRec (subtract 1) $-      takeRec 3 $-        traverseRec (effIO io . print) $-          useImplUnder . x--awaitExample :: IO ()-awaitExample = runEff $ \io -> do-  awaitList [1 :: Int ..] io $ awaitUsage io $ \rec -> do-    replicateM_ 5 (await rec)--consumeStreamExample :: IO (Either String String)-consumeStreamExample = runEff $ \io -> do-  try $ \ex -> do-    consumeStream-      ( \r ->-          bracket-            (effIO io (putStrLn "Starting 2"))-            (\_ -> effIO io (putStrLn "Leaving 2"))-            $ \_ -> do-              for_ [1 :: Int .. 100] $ \n -> do-                b <- await r-                effIO-                  io-                  ( putStrLn-                      ("Consumed body " ++ show b ++ " at time " ++ show n)-                  )-              pure "Consumer finished first"-      )-      ( \y -> bracket-          (effIO io (putStrLn "Starting 1"))-          (\_ -> effIO io (putStrLn "Leaving 1"))-          $ \_ -> do-            for_ [1 :: Int .. 10] $ \n -> do-              effIO io (putStrLn ("Sending " ++ show n))-              yield y n-              when (n > 5) $ do-                effIO io (putStrLn "Aborting...")-                throw ex "Aborted"--            pure "Yielder finished first"-      )--consumeStreamExample2 :: IO ()-consumeStreamExample2 = runEff $ \io -> do-  let counter yeven yodd = for_ [0 :: Int .. 10] $ \i -> do-        if even i-          then yield yeven i-          else yield yodd i--  let foo yeven =-        consumeStream-          ( \r -> forever $ do-              i <- await r-              effIO io (putStrLn ("Odd: " ++ show i))-          )-          (counter yeven)--  let bar =-        consumeStream-          ( \r -> forever $ do-              i <- await r-              effIO io (putStrLn ("Even: " ++ show i))-          )-          foo--  bar--connectExample :: IO (Either String String)-connectExample = runEff $ \io -> do-  try $ \ex -> do-    connectCoroutines-      ( \y -> bracket-          (effIO io (putStrLn "Starting 1"))-          (\_ -> effIO io (putStrLn "Leaving 1"))-          $ \_ -> do-            for_ [1 :: Int .. 10] $ \n -> do-              effIO io (putStrLn ("Sending " ++ show n))-              yield y n-              when (n > 5) $ do-                effIO io (putStrLn "Aborting...")-                throw ex "Aborted"--            pure "Yielder finished first"-      )-      ( \binit r ->-          bracket-            (effIO io (putStrLn "Starting 2"))-            (\_ -> effIO io (putStrLn "Leaving 2"))-            $ \_ -> do-              effIO io (putStrLn ("Consumed intial " ++ show binit))-              for_ [1 :: Int .. 100] $ \n -> do-                b <- await r-                effIO-                  io-                  ( putStrLn-                      ("Consumed body " ++ show b ++ " at time " ++ show n)-                  )-              pure "Consumer finished first"-      )--zipCoroutinesExample :: IO ()-zipCoroutinesExample = runEff $ \io -> do-  let m1 y = do-        r <- yieldCoroutine y 1-        evalModify r $ \rs -> do-          for_ [1 .. 10 :: Int] $ \i -> do-            r' <- get rs-            r'' <- yieldCoroutine y (r' + i)-            put rs r''--  let m2 y = do-        r <- yieldCoroutine y 1-        evalModify r $ \rs -> do-          for_ [1 .. 5 :: Int] $ \i -> do-            r' <- get rs-            r'' <- yieldCoroutine y (r' - i)-            put rs r''--  forEach (\c -> zipCoroutines c m1 m2) $ \i@(i1, i2) -> do-    effIO io (print i)-    pure (i1 + i2)---- Count the number of (strictly) positives and (strictly) negatives--- in a list, unless we see a zero, in which case we bail with an--- error message.-countPositivesNegatives :: [Int] -> String-countPositivesNegatives is = runPureEff $-  evalModify (0 :: Int) $ \positives -> do-    r <- try $ \ex ->-      evalModify (0 :: Int) $ \negatives -> do-        for_ is $ \i -> do-          case compare i 0 of-            GT -> modify positives (+ 1)-            EQ -> throw ex ()-            LT -> modify negatives (+ 1)--        p <- get positives-        n <- get negatives--        pure $-          "Positives: "-            ++ show p-            ++ ", negatives "-            ++ show n--    case r of-      Right r' -> pure r'-      Left () -> do-        p <- get positives-        pure $-          "We saw a zero, but before that there were "-            ++ show p-            ++ " positives"---- How to make compound effects--type MyHandle = Compound (Modify Int) (Throw String)--myInc :: (e <: es) => MyHandle e -> Eff es ()-myInc h = withCompound h (\s _ -> modify s (+ 1))--myBail :: (e <: es) => MyHandle e -> Eff es r-myBail h = withCompound h $ \s e -> do-  i <- get s-  throw e ("Current state was: " ++ show i)--runMyHandle ::-  (forall e. MyHandle e -> Eff (e :& es) a) ->-  Eff es (Either String (a, Int))-runMyHandle f =-  try $ \e -> do-    runModify 0 $ \s -> do-      runCompound s e f--compoundExample :: Either String (a, Int)-compoundExample = runPureEff $ runMyHandle $ \h -> do-  myInc h-  myInc h-  myBail h--countExample :: IO ()-countExample = runEff $ \io -> do-  evalModify @Int 0 $ \sn -> do-    withJump $ \break -> forever $ do-      n <- get sn-      when (n >= 10) (jumpTo break)-      effIO io (print n)-      modify sn (+ 1)--writerExample1 :: Bool-writerExample1 = getAny $ runPureEff $ execWriter $ \w -> do-  for_ [] $ \_ -> tell w (Any True)--writerExample2 :: Bool-writerExample2 = getAny $ runPureEff $ execWriter $ \w -> do-  for_ [1 :: Int .. 10] $ \_ -> tell w (Any True)--while :: Eff es Bool -> Eff es a -> Eff es ()-while condM body =-  withJump $ \break_ -> do-    forever $ do-      cond <- insertFirst condM-      unless cond (jumpTo break_)-      insertFirst body--stateSourceExample :: Int-stateSourceExample = runPureEff $ withStateSource $ \source -> do-  n <- newState source 5-  total <- newState source 0--  withJump $ \done -> forever $ do-    n' <- get n-    modify total (+ n')-    when (n' == 0) $ jumpTo done-    modify n (subtract 1)--  get total--incrementReadLine ::-  (e1 <: es, e2 <: es, e3 <: es) =>-  Modify Int e1 ->-  Throw String e2 ->-  IOE e3 ->-  Eff es ()-incrementReadLine state exception io = do-  withJump $ \break -> forever $ do-    line <- effIO io getLine-    i <- case readMaybe line of-      Nothing ->-        throw exception ("Couldn't read: " ++ line)-      Just i ->-        pure i--    when (i == 0) $-      jumpTo break--    modify state (+ i)--runIncrementReadLine :: IO (Either String Int)-runIncrementReadLine = runEff $ \io -> do-  try $ \exception -> do-    ((), r) <- runModify 0 $ \state -> do-      incrementReadLine state exception io-    pure r---- Counter 1--newtype Counter1 e = MkCounter1 (Modify Int e)--incCounter1 :: (e <: es) => Counter1 e -> Eff es ()-incCounter1 (MkCounter1 st) = modify st (+ 1)--runCounter1 ::-  (forall e. Counter1 e -> Eff (e :& es) r) ->-  Eff es Int-runCounter1 k =-  evalModify 0 $ \st -> do-    _ <- k (MkCounter1 st)-    get st--exampleCounter1 :: Int-exampleCounter1 = runPureEff $ runCounter1 $ \c -> do-  incCounter1 c-  incCounter1 c-  incCounter1 c---- > exampleCounter1--- 3---- Counter 2--data Counter2 e1 e2 = MkCounter2 (Modify Int e1) (Throw () e2)--incCounter2 :: (e1 <: es, e2 <: es) => Counter2 e1 e2 -> Eff es ()-incCounter2 (MkCounter2 st ex) = do-  count <- get st-  when (count >= 10) $-    throw ex ()-  put st (count + 1)--runCounter2 ::-  (forall e1 e2. Counter2 e1 e2 -> Eff (e2 :& e1 :& es) r) ->-  Eff es Int-runCounter2 k =-  evalModify 0 $ \st -> do-    _ <- try $ \ex -> do-      k (MkCounter2 st ex)-    get st--exampleCounter2 :: Int-exampleCounter2 = runPureEff $ runCounter2 $ \c ->-  forever $-    incCounter2 c---- > exampleCounter2--- 10---- Counter 3--data Counter3 e = MkCounter3 (Modify Int e) (Throw () e)--incCounter3 :: (e <: es) => Counter3 e -> Eff es ()-incCounter3 (MkCounter3 st ex) = do-  count <- get st-  when (count >= 10) $-    throw ex ()-  put st (count + 1)--runCounter3 ::-  (forall e. Counter3 e -> Eff (e :& es) r) ->-  Eff es Int-runCounter3 k =-  evalModify 0 $ \st -> do-    _ <- try $ \ex -> do-      useImplIn k (MkCounter3 (mapHandle st) (mapHandle ex))-    get st--exampleCounter3 :: Int-exampleCounter3 = runPureEff $ runCounter3 $ \c ->-  forever $-    incCounter3 c---- > exampleCounter3--- 10---- Counter 3B--newtype Counter3B e = MkCounter3B (IOE e)--incCounter3B :: (e <: es) => Counter3B e -> Eff es ()-incCounter3B (MkCounter3B io) =-  effIO io (putStrLn "You tried to increment the counter")--runCounter3B ::-  (e1 <: es) =>-  IOE e1 ->-  (forall e. Counter3B e -> Eff (e :& es) r) ->-  Eff es r-runCounter3B io k = useImplIn k (MkCounter3B (mapHandle io))--exampleCounter3B :: IO ()-exampleCounter3B = runEff $ \io -> runCounter3B io $ \c -> do-  incCounter3B c-  incCounter3B c-  incCounter3B c---- ghci> exampleCounter3B--- You tried to increment the counter--- You tried to increment the counter--- You tried to increment the counter---- Counter 4--data Counter4 e-  = MkCounter4 (Modify Int e) (Throw () e) (Stream String e)--incCounter4 :: (e <: es) => Counter4 e -> Eff es ()-incCounter4 (MkCounter4 st ex y) = do-  count <- get st--  when (even count) $-    yield y "Count was even"--  when (count >= 10) $-    throw ex ()--  put st (count + 1)--getCounter4 :: (e <: es) => Counter4 e -> String -> Eff es Int-getCounter4 (MkCounter4 st _ y) msg = do-  yield y msg-  get st--runCounter4 ::-  (e1 <: es) =>-  Stream String e1 ->-  (forall e. Counter4 e -> Eff (e :& es) r) ->-  Eff es Int-runCounter4 y k =-  evalModify 0 $ \st -> do-    _ <- try $ \ex -> do-      useImplIn k (MkCounter4 (mapHandle st) (mapHandle ex) (mapHandle y))-    get st--exampleCounter4 :: ([String], Int)-exampleCounter4 = runPureEff $ yieldToList $ \y -> do-  runCounter4 y $ \c -> do-    incCounter4 c-    incCounter4 c-    n <- getCounter4 c "I'm getting the counter"-    when (n == 2) $-      yield y "n was 2, as expected"---- > exampleCounter4--- (["Count was even","I'm getting the counter","n was 2, as expected"],2)---- Counter 5--data Counter5 e = MkCounter5-  { incCounter5Impl :: Eff e (),-    getCounter5Impl :: String -> Eff e Int-  }-  deriving (Generic)-  deriving (Handle) via OneWayCoercibleHandle Counter5--instance (e <: es) => OneWayCoercible (Counter5 e) (Counter5 es) where-  oneWayCoercibleImpl = gOneWayCoercible--incCounter5 :: (e <: es) => Counter5 e -> Eff es ()-incCounter5 e = incCounter5Impl (mapHandle e)--getCounter5 :: (e <: es) => Counter5 e -> String -> Eff es Int-getCounter5 e msg = getCounter5Impl (mapHandle e) msg--runCounter5 ::-  (e1 <: es) =>-  Stream String e1 ->-  (forall e. Counter5 e -> Eff (e :& es) r) ->-  Eff es Int-runCounter5 y k =-  evalModify 0 $ \st -> do-    _ <- try $ \ex -> do-      useImplIn-        k-        ( MkCounter5-            { incCounter5Impl = do-                count <- get st--                when (even count) $-                  yield y "Count was even"--                when (count >= 10) $-                  throw ex ()--                put st (count + 1),-              getCounter5Impl = \msg -> do-                yield y msg-                get st-            }-        )-    get st--exampleCounter5 :: ([String], Int)-exampleCounter5 = runPureEff $ yieldToList $ \y -> do-  runCounter5 y $ \c -> do-    incCounter5 c-    incCounter5 c-    n <- getCounter5 c "I'm getting the counter"-    when (n == 2) $-      yield y "n was 2, as expected"---- > exampleCounter5--- (["Count was even","I'm getting the counter","n was 2, as expected"],2)---- Counter 6--data Counter6 e = MkCounter6-  { incCounter6Impl :: Eff e (),-    counter6Modify :: Modify Int e,-    counter6Stream :: Stream String e-  }-  deriving (Generic)-  deriving (Handle) via OneWayCoercibleHandle Counter6--instance (e <: es) => OneWayCoercible (Counter6 e) (Counter6 es) where-  oneWayCoercibleImpl = gOneWayCoercible--incCounter6 :: (e <: es) => Counter6 e -> Eff es ()-incCounter6 e = incCounter6Impl (mapHandle e)--getCounter6 :: (e <: es) => Counter6 e -> String -> Eff es Int-getCounter6 (MkCounter6 _ st y) msg = do-  yield y msg-  get st--runCounter6 ::-  (e1 <: es) =>-  Stream String e1 ->-  (forall e. Counter6 e -> Eff (e :& es) r) ->-  Eff es Int-runCounter6 y k =-  evalModify 0 $ \st -> do-    _ <- try $ \ex -> do-      useImplIn-        k-        ( MkCounter6-            { incCounter6Impl = do-                count <- get st--                when (even count) $-                  yield y "Count was even"--                when (count >= 10) $-                  throw ex ()--                put st (count + 1),-              counter6Modify = mapHandle st,-              counter6Stream = mapHandle y-            }-        )-    get st--exampleCounter6 :: ([String], Int)-exampleCounter6 = runPureEff $ yieldToList $ \y -> do-  runCounter6 y $ \c -> do-    incCounter6 c-    incCounter6 c-    n <- getCounter6 c "I'm getting the counter"-    when (n == 2) $-      yield y "n was 2, as expected"---- > exampleCounter6--- (["Count was even","I'm getting the counter","n was 2, as expected"],2)---- Counter 7--data Counter7 e = MkCounter7-  { incCounter7Impl :: forall e'. Throw () e' -> Eff (e' :& e) (),-    counter7Modify :: Modify Int e,-    counter7Stream :: Stream String e-  }-  deriving (Handle) via OneWayCoercibleHandle Counter7---- | The "forall" in the type of @incCounter7@ means that we can't--- derive the @OneWayCoercible@ instance with 'gOneWayCoercible' so--- instead we use @oneWayCoercibleTrustMe@.-instance (e <: es) => OneWayCoercible (Counter7 e) (Counter7 es) where-  oneWayCoercibleImpl = oneWayCoercibleTrustMe $ \c ->-    MkCounter7-      { incCounter7Impl = \ex -> useImplUnder (incCounter7Impl c ex),-        counter7Modify = mapHandle (counter7Modify c),-        counter7Stream = mapHandle (counter7Stream c)-      }--incCounter7 ::-  (e <: es, e1 <: es) => Counter7 e -> Throw () e1 -> Eff es ()-incCounter7 e ex = makeOp (incCounter7Impl (mapHandle e) (mapHandle ex))--getCounter7 :: (e <: es) => Counter7 e -> String -> Eff es Int-getCounter7 (MkCounter7 _ st y) msg = do-  yield y msg-  get st--runCounter7 ::-  (e1 <: es) =>-  Stream String e1 ->-  (forall e. Counter7 e -> Eff (e :& es) r) ->-  Eff es Int-runCounter7 y k =-  evalModify 0 $ \st -> do-    _ <--      useImplIn-        k-        ( MkCounter7-            { incCounter7Impl = \ex -> do-                count <- get st--                when (even count) $-                  yield y "Count was even"--                when (count >= 10) $-                  throw ex ()--                put st (count + 1),-              counter7Modify = mapHandle st,-              counter7Stream = mapHandle y-            }-        )-    get st--exampleCounter7A :: ([String], Int)-exampleCounter7A = runPureEff $ yieldToList $ \y -> do-  handle (\() -> pure (-42)) $ \ex ->-    runCounter7 y $ \c -> do-      incCounter7 c ex-      incCounter7 c ex-      n <- getCounter7 c "I'm getting the counter"-      when (n == 2) $-        yield y "n was 2, as expected"---- > exampleCounter7A--- (["Count was even","I'm getting the counter","n was 2, as expected"],2)--exampleCounter7B :: ([String], Int)-exampleCounter7B = runPureEff $ yieldToList $ \y -> do-  handle (\() -> pure (-42)) $ \ex ->-    runCounter7 y $ \c -> do-      forever (incCounter7 c ex)---- > exampleCounter7B--- (["Count was even","Count was even","Count was even","Count was even","Count was even","Count was even"],-42)---- FileSystem--data FileSystem es = MkFileSystem-  { readFileImpl :: FilePath -> Eff es String,-    writeFileImpl :: FilePath -> String -> Eff es ()-  }-  deriving (Generic)-  deriving (Handle) via OneWayCoercibleHandle FileSystem--instance (e <: es) => OneWayCoercible (FileSystem e) (FileSystem es) where-  oneWayCoercibleImpl = gOneWayCoercible--readFile :: (e <: es) => FileSystem e -> FilePath -> Eff es String-readFile fs filepath = readFileImpl (mapHandle fs) filepath--writeFile :: (e <: es) => FileSystem e -> FilePath -> String -> Eff es ()-writeFile fs filepath contents =-  writeFileImpl (mapHandle fs) filepath contents--runFileSystemPure ::-  (e1 <: es) =>-  Throw String e1 ->-  [(FilePath, String)] ->-  (forall e2. FileSystem e2 -> Eff (e2 :& es) r) ->-  Eff es r-runFileSystemPure ex fs0 k =-  evalModify fs0 $ \fs ->-    useImplIn-      k-      MkFileSystem-        { readFileImpl = \path -> do-            fs' <- get fs-            case lookup path fs' of-              Nothing ->-                throw ex ("File not found: " <> path)-              Just s -> pure s,-          writeFileImpl = \path contents ->-            modify fs ((path, contents) :)-        }--runFileSystemIO ::-  forall e1 e2 es r.-  (e1 <: es, e2 <: es) =>-  Throw String e1 ->-  IOE e2 ->-  (forall e. FileSystem e -> Eff (e :& es) r) ->-  Eff es r-runFileSystemIO ex io k =-  useImplIn-    k-    MkFileSystem-      { readFileImpl =-          adapt . Prelude.readFile,-        writeFileImpl =-          \path -> adapt . Prelude.writeFile path-      }-  where-    adapt :: (e1 <: ess, e2 <: ess) => IO a -> Eff ess a-    adapt m =-      effIO io (Control.Exception.try @IOException m) >>= \case-        Left e -> throw ex (show e)-        Right r -> pure r--action :: (e <: es) => FileSystem e -> Eff es String-action fs = do-  file <- readFile fs "/dev/null"-  when (length file == 0) $ do-    writeFile fs "/tmp/bluefin" "Hello!\n"-  readFile fs "/tmp/doesn't exist"--exampleRunFileSystemPure :: Either String String-exampleRunFileSystemPure = runPureEff $ try $ \ex ->-  runFileSystemPure ex [("/dev/null", "")] action---- > exampleRunFileSystemPure--- Left "File not found: /tmp/doesn't exist"--exampleRunFileSystemIO :: IO (Either String String)-exampleRunFileSystemIO = runEff $ \io -> try $ \ex ->-  runFileSystemIO ex io action---- > exampleRunFileSystemIO--- Left "/tmp/doesn't exist: openFile: does not exist (No such file or directory)"--- \$ cat /tmp/bluefin--- Hello!---- instance Handle example--data Application e = MkApplication-  { queryDatabase :: String -> Int -> Eff e [String],-    applicationModify :: Modify (Int, Bool) e,-    logger :: Stream String e-  }-  deriving (Generic)-  deriving (Handle) via OneWayCoercibleHandle Application--instance (e <: es) => OneWayCoercible (Application e) (Application es) where-  oneWayCoercibleImpl = gOneWayCoercible---- This example shows a case where we can use @bracket@ polymorphically--- in order to perform correct cleanup if @es@ is instantiated to a--- set of effects that includes exceptions.-polymorphicBracket ::-  (st <: es) =>-  Modify (Integer, Bool) st ->-  Eff es () ->-  Eff es ()-polymorphicBracket st act =-  bracket-    (pure ())-    -- Always set the boolean indicating that we have terminated-    (\_ -> modify st (\(c, _b) -> (c, True)))-    -- Perform the given effectful action, then increment the counter-    (\_ -> do act; modify st (\(c, b) -> ((c + 1), b)))---- Results in (1, True)-polymorphicBracketExample1 :: (Integer, Bool)-polymorphicBracketExample1 =-  runPureEff $ do-    (_res, st) <- runModify (0, False) $ \st -> polymorphicBracket st (pure ())-    pure st---- Results in (0, True)-polymorphicBracketExample2 :: (Integer, Bool)-polymorphicBracketExample2 =-  runPureEff $ do-    (_res, st) <- runModify (0, False) $ \st -> try @Int $ \e -> polymorphicBracket st (throw e 42)-    pure st--pipesExample1 :: IO ()-pipesExample1 = runEff $ \io -> runEffect (count >-> P.print io)-  where-    count :: (e <: es) => Producer Int e -> Eff es ()-    count p = for_ [1 .. 5] $ \i -> P.yield p i--pipesExample2 :: IO String-pipesExample2 = runEff $ \io -> runEffect $ do-  stdinLn io >-> takeWhile' (/= "quit") >-> stdoutLn io---- Acquiring resource--- 1--- 2--- 3--- 4--- 5--- Releasing resource--- Finishing-promptCoroutine :: IO ()-promptCoroutine = runEff $ \io -> do-  -- consumeStream connects a consumer to a producer-  consumeStream-    -- Like a pipes Consumer.  Prints the first five elements it-    -- awaits.-    ( \r -> for_ [1 :: Int .. 5] $ \_ -> do-        v <- await r-        effIO io (print v)-    )-    -- Like a pipes Producer. Yields successive integers indefinitely.-    -- Unlike in pipes, we can simply use Bluefin's standard bracket-    -- for prompt release of a resource-    ( \y ->-        bracket-          (effIO io (putStrLn "Acquiring resource"))-          (\_ -> effIO io (putStrLn "Releasing resource"))-          (\_ -> 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---- | The "forall" in the type of @localRImpl@ means that we can't--- derive the @OneWayCoercible@ instance with 'gOneWayCoercible' so--- instead we use @oneWayCoercibleTrustMe@.-data DynamicReader r e = DynamicReader-  { askLRImpl :: Eff e r,-    localLRImpl :: forall e' a. (r -> r) -> Eff e' a -> Eff (e' :& e) a-  }-  deriving (Handle) via OneWayCoercibleHandle (DynamicReader r)--instance-  (e <: es) =>-  OneWayCoercible (DynamicReader r e) (DynamicReader r es)-  where-  oneWayCoercibleImpl = oneWayCoercibleTrustMe $ \h ->-    DynamicReader-      { askLRImpl = useImpl (askLRImpl h),-        localLRImpl = \f k -> useImplUnder (localLRImpl h f k)-      }--askLR ::-  (e <: es) =>-  DynamicReader r e ->-  Eff es r-askLR c = askLRImpl (mapHandle c)--localLR ::-  (e <: es) =>-  DynamicReader r e ->-  (r -> r) ->-  Eff es a ->-  Eff es a-localLR c f m = makeOp (localLRImpl (mapHandle c) f m)--runDynamicReader ::-  r ->-  (forall e. DynamicReader r e -> Eff (e :& es) a) ->-  Eff es a-runDynamicReader r k =-  runReader r $ \h -> do-    useImplIn-      k-      DynamicReader-        { askLRImpl = ask h,-          localLRImpl = \f k' -> local h f (useImpl k')-        }+module Bluefin.Internal.Examples where++import Bluefin.Internal+import Data.Proxy (Proxy (Proxy))  -- Fails to compile unless '(e <: es) => e <: (x :& es)' is incoherent -- (otherwise I guess it "commits to it too soon")
src/Bluefin/Internal/Pipes.hs view
@@ -14,7 +14,7 @@     returnEarly,     useImpl,     useImplIn,-    withEarlyReturn,+    withReturnEarly,     yieldCoroutine,     (:&),     type (<:),@@ -211,7 +211,7 @@   -- | ͘   Eff es r unfoldr next_ sInit p =-  withEarlyReturn $ \break -> evalState sInit $ \ss -> forever $ do+  withReturnEarly $ \break -> evalState sInit $ \ss -> forever $ do     s <- get ss     useImpl (next_ s) >>= \case       Left r -> returnEarly break r@@ -258,7 +258,7 @@   Pipe r r e ->   -- | ͘   Eff es r-takeWhile' predicate p = withEarlyReturn $ \early -> forever $ do+takeWhile' predicate p = withReturnEarly $ \early -> forever $ do   a <- await p   if predicate a     then yield p a