packages feed

fx 0.7 → 0.10

raw patch · 6 files changed

+131/−83 lines, 6 filesdep −base-preludedep −transformersdep ~basePVP ok

version bump matches the API change (PVP)

Dependencies removed: base-prelude, transformers

Dependency ranges changed: base

API changes (from Hackage documentation)

- Fx.EitherEffect: executor :: Executor effect1 context -> Executor effect2 context -> Executor (EitherEffect effect1 effect2 context) context
- Fx.EitherEffect: instance Control.Monad.IO.Class.MonadIO context => Control.Monad.IO.Class.MonadIO (Fx.EitherEffect.EitherEffect effect1 effect2 context)
- Fx.EitherEffect: instance Control.Monad.Trans.Class.MonadTrans (Fx.EitherEffect.EitherEffect effect1 effect2)
- Fx.EitherEffect: instance GHC.Base.Alternative context => GHC.Base.Alternative (Fx.EitherEffect.EitherEffect effect1 effect2 context)
- Fx.EitherEffect: instance GHC.Base.Applicative context => GHC.Base.Applicative (Fx.EitherEffect.EitherEffect effect1 effect2 context)
- Fx.EitherEffect: instance GHC.Base.Functor context => GHC.Base.Functor (Fx.EitherEffect.EitherEffect effect1 effect2 context)
- Fx.EitherEffect: instance GHC.Base.Monad context => GHC.Base.Monad (Fx.EitherEffect.EitherEffect effect1 effect2 context)
- Fx.EitherEffect: instance GHC.Base.MonadPlus context => GHC.Base.MonadPlus (Fx.EitherEffect.EitherEffect effect1 effect2 context)
- Fx.EitherEffect: liftEffect1 :: effect1 result -> EitherEffect effect1 effect2 context result
- Fx.EitherEffect: liftEffect2 :: effect2 result -> EitherEffect effect1 effect2 context result
- Fx.Executor: Executor :: (forall result. effect result -> context result) -> Executor effect context
- Fx.Executor: execute :: Executor effect context -> effect result -> context result
- Fx.Executor: mapContext :: (forall result. oldContext result -> newContext result) -> Executor effect oldContext -> Executor effect newContext
- Fx.Executor: mapEffect :: (forall result. newEffect result -> oldEffect result) -> Executor oldEffect context -> Executor newEffect context
- Fx.Executor: newtype Executor effect context
+ Fx.EitherEffect: instance Control.Monad.IO.Class.MonadIO either => Control.Monad.IO.Class.MonadIO (Fx.EitherEffect.Types.EitherEffect left right either)
+ Fx.EitherEffect: instance GHC.Base.Applicative either => GHC.Base.Applicative (Fx.EitherEffect.Types.EitherEffect left right either)
+ Fx.EitherEffect: instance GHC.Base.Functor either => GHC.Base.Functor (Fx.EitherEffect.Types.EitherEffect left right either)
+ Fx.EitherEffect: instance GHC.Base.Monad either => GHC.Base.Monad (Fx.EitherEffect.Types.EitherEffect left right either)
+ Fx.EitherEffect: liftLeft :: left result -> EitherEffect left right either result
+ Fx.EitherEffect: liftRight :: right result -> EitherEffect left right either result
+ Fx.Transform: Transform :: (forall result. input result -> output result) -> (-->) input output
+ Fx.Transform: eitherEffect :: Monad either => (left --> either) -> (right --> either) -> (EitherEffect left right either --> either)
+ Fx.Transform: instance Control.Category.Category (Fx.Transform.-->)
+ Fx.Transform: newtype input (-->) output
- Fx.EitherEffect: data EitherEffect effect1 effect2 context result
+ Fx.EitherEffect: data EitherEffect leftEffect rightEffect context result

Files

fx.cabal view
@@ -1,7 +1,7 @@ name:   fx version:-  0.7+  0.10 synopsis:   Horizontally composable effects description:@@ -43,10 +43,9 @@     Haskell2010   exposed-modules:     Fx.EitherEffect-    Fx.Executor+    Fx.Transform   other-modules:+    Fx.EitherEffect.Types     Fx.Prelude   build-depends:-    transformers >= 0.3 && < 0.6,-    base-prelude >= 1 && < 2,-    base >= 4.6 && < 5+    base >= 4.10 && < 5
library/Fx/EitherEffect.hs view
@@ -1,48 +1,47 @@ module Fx.EitherEffect (   EitherEffect,-  liftEffect1,-  liftEffect2,-  executor,+  liftLeft,+  liftRight, ) where  import Fx.Prelude-import qualified Fx.Executor as A+import Fx.EitherEffect.Types  -{-|-A sum of two effects (@effect1@ and @effect2@) to be executed-in @context@ producing @result@.--}-newtype EitherEffect effect1 effect2 context result =-  EitherEffect (ReaderT (A.Executor effect1 context, A.Executor effect2 context) context result)-  deriving (Functor, Applicative, Alternative, Monad, MonadPlus, MonadIO)+instance Functor either => Functor (EitherEffect left right either) where+  fmap mapping (EitherEffect either) =+    EitherEffect (\ leftContext rightContext -> fmap mapping (either leftContext rightContext)) -instance MonadTrans (EitherEffect effect1 effect2) where-  lift =-    EitherEffect . lift+instance Applicative either => Applicative (EitherEffect left right either) where+  pure x =+    EitherEffect (\ _ _ -> pure x)+  (<*>) (EitherEffect left) (EitherEffect right) =+    EitherEffect (\ leftContext rightContext -> left leftContext rightContext <*> right leftContext rightContext) +instance Monad either => Monad (EitherEffect left right either) where+  return = pure+  (>>=) (EitherEffect left) rightK =+    EitherEffect $ \ leftContext rightContext -> do+      leftResult <- left leftContext rightContext+      case rightK leftResult of+        EitherEffect right -> right leftContext rightContext++instance MonadIO either => MonadIO (EitherEffect left right either) where+  liftIO io =+    EitherEffect (\ _ _ -> liftIO io)+ {-| Lift the first of the two effects. -}-liftEffect1 :: effect1 result -> EitherEffect effect1 effect2 context result-liftEffect1 effect =-  EitherEffect (ReaderT (\(executor, _) -> A.execute executor effect))+liftLeft :: left result -> EitherEffect left right either result+liftLeft effect =+  EitherEffect (\ leftContext rightContext -> leftContext effect)  {-| Lift the second of the two effects. -}-liftEffect2 :: effect2 result -> EitherEffect effect1 effect2 context result-liftEffect2 effect =-  EitherEffect (ReaderT (\(_, executor) -> A.execute executor effect))--{-|-Compose the executors of each effect into an executor of either.--}-executor-  :: A.Executor effect1 context-  -> A.Executor effect2 context-  -> A.Executor (EitherEffect effect1 effect2 context) context-executor executor1 executor2 =-  A.Executor (\(EitherEffect reader) -> runReaderT reader (executor1, executor2))+liftRight :: right result -> EitherEffect left right either result+liftRight effect =+  EitherEffect (\ leftContext rightContext -> rightContext effect)
+ library/Fx/EitherEffect/Types.hs view
@@ -0,0 +1,13 @@+module Fx.EitherEffect.Types+where++import Fx.Prelude++{-|+A sum of two effects.+Allows for horizontal composition of monads instead of nesting as with monad transformers.++To execute it use 'Fx.Transform.eitherEffect'.+-}+newtype EitherEffect leftEffect rightEffect context result =+  EitherEffect ((forall x. leftEffect x -> context x) -> (forall x. rightEffect x -> context x) -> context result)
− library/Fx/Executor.hs
@@ -1,38 +0,0 @@-module Fx.Executor-(-  Executor(..),-  mapEffect,-  mapContext,-  execute,-)-where--import Fx.Prelude---{-|-An abstraction over the execution of @effect@ in @context@, both producing the same @result@.--}-newtype Executor effect context =-  Executor (forall result. effect result -> context result)--{-|-Use the executor to run an effect in a context.--}-execute :: Executor effect context -> effect result -> context result-execute (Executor def) effect =-  def effect--{-|-Map the effect part of an executor (contravariantly).--}-mapEffect :: (forall result. newEffect result -> oldEffect result) -> Executor oldEffect context -> Executor newEffect context-mapEffect mapping (Executor fn) =-  Executor (fn . mapping)--{-|-Map the context part of an executor.--}-mapContext :: (forall result. oldContext result -> newContext result) -> Executor effect oldContext -> Executor effect newContext-mapContext mapping (Executor fn) =-  Executor (mapping . fn)
library/Fx/Prelude.hs view
@@ -5,18 +5,68 @@ where  --- base-prelude+-- base --------------------------import BasePrelude as Exports hiding (assert, left, right, isLeft, isRight, (<>), First(..), Last(..), ProtocolError, traceEvent, traceEventIO, traceMarker, traceMarkerIO) +import Control.Applicative as Exports+import Control.Arrow as Exports hiding (first, second)+import Control.Category as Exports+import Control.Concurrent as Exports+import Control.Exception as Exports+import Control.Monad as Exports hiding (mapM_, sequence_, forM_, msum, mapM, sequence, forM)+import Control.Monad.Fix as Exports hiding (fix)+import Control.Monad.ST as Exports+import Data.Bits as Exports+import Data.Bool as Exports hiding (bool)+import Data.Char as Exports+import Data.Complex as Exports+import Data.Data as Exports+import Data.Dynamic as Exports+import Data.Either as Exports+import Data.Fixed as Exports+import Data.Foldable as Exports+import Data.Function as Exports hiding ((.), id, (&))+import Data.Functor as Exports hiding (($>))+import Data.Int as Exports+import Data.IORef as Exports+import Data.Ix as Exports+import Data.List as Exports hiding (sortOn, isSubsequenceOf, uncons, concat, foldr, foldl1, maximum, minimum, product, sum, all, and, any, concatMap, elem, foldl, foldr1, notElem, or, find, maximumBy, minimumBy, mapAccumL, mapAccumR, foldl')+import Data.Maybe as Exports+import Data.Monoid as Exports+import Data.Ord as Exports+import Data.Ratio as Exports+import Data.STRef as Exports+import Data.String as Exports+import Data.Traversable as Exports+import Data.Tuple as Exports+import Data.Unique as Exports+import Data.Version as Exports+import Data.Word as Exports+import Debug.Trace as Exports hiding (traceShowId, traceM, traceShowM)+import Foreign.ForeignPtr as Exports+import Foreign.Ptr as Exports+import Foreign.StablePtr as Exports+import Foreign.Storable as Exports+import GHC.Conc as Exports hiding (withMVar, threadWaitWriteSTM, threadWaitWrite, threadWaitReadSTM, threadWaitRead)+import GHC.Exts as Exports (lazy, inline, sortWith, groupWith)+import GHC.Generics as Exports (Generic)+import GHC.IO.Exception as Exports+import Numeric as Exports+import Prelude as Exports hiding (concat, foldr, mapM_, sequence_, foldl1, maximum, minimum, product, sum, all, and, any, concatMap, elem, foldl, foldr1, notElem, or, mapM, sequence, id, (.))+import System.Environment as Exports+import System.Exit as Exports+import System.IO as Exports (Handle, hClose)+import System.IO.Error as Exports+import System.IO.Unsafe as Exports+import System.Mem as Exports+import System.Mem.StableName as Exports+import System.Timeout as Exports+import Text.ParserCombinators.ReadP as Exports (ReadP, ReadS, readP_to_S, readS_to_P)+import Text.ParserCombinators.ReadPrec as Exports (ReadPrec, readPrec_to_P, readP_to_Prec, readPrec_to_S, readS_to_Prec)+import Text.Printf as Exports (printf, hPrintf)+import Text.Read as Exports (Read(..), readMaybe, readEither)+import Unsafe.Coerce as Exports+ -- transformers ------------------------- import Control.Monad.IO.Class as Exports-import Control.Monad.Trans.Class as Exports-import Control.Monad.Trans.Cont as Exports hiding (shift, callCC)-import Control.Monad.Trans.Except as Exports (ExceptT(ExceptT), Except, except, runExcept, runExceptT, mapExcept, mapExceptT, withExcept, withExceptT, throwE, catchE)-import Control.Monad.Trans.Maybe as Exports-import Control.Monad.Trans.Reader as Exports (Reader, runReader, mapReader, withReader, ReaderT(ReaderT), runReaderT, mapReaderT, withReaderT)-import Control.Monad.Trans.State.Strict as Exports (State, runState, evalState, execState, mapState, withState, StateT(StateT), runStateT, evalStateT, execStateT, mapStateT, withStateT)-import Control.Monad.Trans.Writer.Strict as Exports (Writer, runWriter, execWriter, mapWriter, WriterT(..), execWriterT, mapWriterT)-import Data.Functor.Compose as Exports
+ library/Fx/Transform.hs view
@@ -0,0 +1,25 @@+module Fx.Transform+where++import Fx.Prelude+import Fx.EitherEffect.Types+++{-|+Natural transformation.+An abstraction over the transformation of kind-2 @input@ to @output@, both producing the same @result@.+-}+newtype input --> output =+  Transform (forall result. input result -> output result)++{-|+Given a natural transformation of the left monad and a natural transformation of the right monad,+produces a natural transformation of either of them.+-}+eitherEffect :: Monad either => (left --> either) -> (right --> either) -> (EitherEffect left right either --> either)+eitherEffect (Transform leftTrans) (Transform rightTrans) =+  Transform (\ (EitherEffect context) -> context leftTrans rightTrans)++instance Category (-->) where+  id = Transform id+  (.) (Transform left) (Transform right) = Transform (left . right)