bluefin-internal 0.0.0.0 → 0.0.1.0
raw patch · 5 files changed
+83/−27 lines, 5 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
+ Bluefin.Internal: Writer :: Stream w e -> Writer w e
+ Bluefin.Internal: execWriter :: Monoid w => (forall e. Writer w e -> Eff (e :& es) r) -> Eff es w
+ Bluefin.Internal: newtype Writer w e
+ Bluefin.Internal: runWriter :: Monoid w => (forall e. Writer w e -> Eff (e :& es) r) -> Eff es (r, w)
+ Bluefin.Internal: tell :: e :> es => Writer w e -> w -> Eff es ()
+ Bluefin.Internal.Examples: writerExample1 :: Bool
+ Bluefin.Internal.Examples: writerExample2 :: Bool
Files
- CHANGELOG.md +4/−0
- bluefin-internal.cabal +1/−1
- src/Bluefin/Internal.hs +54/−0
- src/Bluefin/Internal/Examples.hs +10/−1
- test/Main.hs +14/−25
CHANGELOG.md view
@@ -1,3 +1,7 @@+## 0.0.1.0++* Add `Bluefin.Internal.Writer`+ ## 0.0.0.0 * Initial version
bluefin-internal.cabal view
@@ -1,6 +1,6 @@ cabal-version: 3.0 name: bluefin-internal-version: 0.0.0.0+version: 0.0.1.0 license: MIT license-file: LICENSE author: Tom Ellis
src/Bluefin/Internal.hs view
@@ -770,3 +770,57 @@ pure $ case r of Right r' -> Right r' Left (l, _) -> Left l++newtype Writer w e = Writer (Stream w e)++-- |+-- @+-- >>> 'Data.Monoid.getAny' $ snd $ runPureEff $ runWriter $ \\w -> do+-- -- Non-empty list (the tell event does happen)+-- for_ [1 .. 10] $ \\_ -> tell w ('Data.Monoid.Any' True)+-- True+-- @+runWriter ::+ (Monoid w) =>+ -- | ͘+ (forall e. Writer w e -> Eff (e :& es) r) ->+ Eff es (r, w)+runWriter f = runState mempty $ \st -> do+ forEach (insertSecond . f . Writer) $ \ww -> do+ modify st (<> ww)++-- |+-- @+-- >>> 'Data.Monoid.getAny' $ runPureEff $ execWriter $ \\w -> do+-- -- Non-empty list (the tell event does happen)+-- for_ [1 .. 10] $ \\_ -> tell w ('Data.Monoid.Any' True)+-- True+-- @+--+-- @+-- >>> 'Data.Monoid.getAny' $ runPureEff $ execWriter $ \\w -> do+-- -- Empty list (the tell event does not happen)+-- for_ [] $ \\_ -> tell w ('Data.Monoid.Any' True)+-- False+-- @+execWriter ::+ (Monoid w) =>+ -- | ͘+ (forall e. Writer w e -> Eff (e :& es) r) ->+ Eff es w+execWriter f = fmap snd (runWriter f)++-- |+-- @+-- >>> 'Data.Monoid.getAny' $ runPureEff $ execWriter $ \\w -> do+-- -- Non-empty list (the tell event does happen)+-- for_ [1 .. 10] $ \\_ -> tell w ('Data.Monoid.Any' True)+-- True+-- @+tell ::+ (e :> es) =>+ Writer w e ->+ -- | ͘+ w ->+ Eff es ()+tell (Writer y) = yield y
src/Bluefin/Internal/Examples.hs view
@@ -3,10 +3,11 @@ module Bluefin.Internal.Examples where -import Bluefin.Internal+import Bluefin.Internal hiding (w) import Control.Monad (forever, when) import Control.Monad.IO.Class (liftIO) import Data.Foldable (for_)+import Data.Monoid (Any (Any, getAny)) import Prelude hiding (break, drop, head, read, return) monadIOExample :: IO ()@@ -194,3 +195,11 @@ 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 .. 10] $ \_ -> tell w (Any True)
test/Main.hs view
@@ -6,12 +6,13 @@ import Bluefin.Internal import Control.Monad (when) import Data.Foldable (for_)+import Data.Monoid (All (All)) import System.Exit (ExitCode (ExitFailure), exitWith) import Prelude hiding (break, read) main :: IO () main = do- allTrue $ \y -> do+ runSpecH $ \y -> do let assertEqual' = assertEqual y assertEqual' "oddsUntilFirstGreaterThan5" oddsUntilFirstGreaterThan5 [1, 3, 5, 7]@@ -39,18 +40,6 @@ -- (name, Maybe (stream of error text)) type SpecH = Stream (String, Maybe (SpecInfo ())) --- I'm still not convinced that this scheme is practical for calling--- outer effects from the inner. The problem is that at the time of--- interpretation some outer effects are unavailable because they have--- already been handled (for example some state which the test cases--- use) or, in the case of the Stream effect itself, because they are--- currently being handled (we can't yield more results to the Stream--- whilst we're handling it).------ It seems likely that with a lot of awkwardness we can arrange for--- the type parameters to be compatible with the order of handling,--- but then we've coupled the order of the handlers to the effectful--- operation, which is antithetical to the point of Bluefin. assertEqual :: (e :> es, Eq a, Show a) => SpecH e -> String -> a -> a -> Eff es () assertEqual y n c1 c2 =@@ -82,19 +71,19 @@ Stream String e3 -> Eff es Bool runTests f y = do- evalState True $ \(passedAllSoFar :: State Bool e2) -> do- forEach f $ \(name, passedThisOne) -> do- case passedThisOne of- Just _ -> put passedAllSoFar False- Nothing -> pure ()+ ((), All passedAll) <- runWriter $ \passedAllSoFar -> do+ forEach f $ \(name, mFailure) -> do+ let passed = case mFailure of+ Just _ -> False+ Nothing -> True - let mark = case passedThisOne of- Nothing -> "✓"- Just _ -> "✗"+ tell passedAllSoFar (All passed) + let mark = if passed then "✓" else "✗"+ yield y (mark ++ " " ++ name) - case passedThisOne of+ case mFailure of Nothing -> pure () Just n -> do yield y "" :: Eff (e2 :& es) ()@@ -102,12 +91,12 @@ yield y (" " ++ entry) yield y "" - get passedAllSoFar+ pure passedAll -allTrue ::+runSpecH :: (forall e1 es. SpecH e1 -> Eff (e1 :& es) ()) -> IO ()-allTrue f = runEff $ \ioe -> do+runSpecH f = runEff $ \ioe -> do passed <- forEach (runTests f) $ \text -> effIO ioe (putStrLn text)