simple-effects 0.2.0.0 → 0.2.0.1
raw patch · 3 files changed
+66/−3 lines, 3 filesdep +list-tdep ~interlude-lPVP: minor bump suggested
API additions: PVP suggests at least a minor version bump
Dependencies added: list-t
Dependency ranges changed: interlude-l
API changes (from Hackage documentation)
+ Control.Effects.List: choose :: MonadEffect1 List m => [a] -> m a
+ Control.Effects.List: data List
+ Control.Effects.List: deadEnd :: MonadEffect1 List m => m a
+ Control.Effects.List: evaluateNResults :: Monad m => Int -> EffectHandler1 List (ListT m) a -> m [a]
+ Control.Effects.List: evaluateOneResult :: Monad m => EffectHandler1 List (ListT m) a -> m (Maybe a)
+ Control.Effects.List: evaluateToList :: Monad m => EffectHandler1 List (ListT m) a -> m [a]
+ Control.Effects.List: foldAllResults :: Monad m => (r -> a -> m r) -> r -> EffectHandler1 List (ListT m) a -> m r
+ Control.Effects.List: foldWithEarlyTermination :: Monad m => (r -> a -> m (Maybe r)) -> r -> EffectHandler1 List (ListT m) a -> m r
+ Control.Effects.List: handleList :: Monad m => (ListT m a -> m b) -> EffectHandler1 List (ListT m) a -> m b
+ Control.Effects.List: test :: IO (Maybe Int)
+ Control.Effects.List: traverseAllResults :: Monad m => (a -> m ()) -> EffectHandler1 List (ListT m) a -> m ()
Files
- simple-effects.cabal +5/−2
- src/Control/Effects/List.hs +60/−0
- src/Control/Effects1.hs +1/−1
simple-effects.cabal view
@@ -1,5 +1,5 @@ name: simple-effects-version: 0.2.0.0+version: 0.2.0.1 synopsis: A simple effect system that integrates with MTL description: Please see README.md homepage: https://gitlab.com/LukaHorvat/simple-effects@@ -17,15 +17,18 @@ , Control.Effects1 , Control.Effects.State , Control.Effects.Reader+ , Control.Effects.List hs-source-dirs: src default-language: Haskell2010 build-depends: base >= 4.7 && < 5 , transformers , mtl- , interlude-l+ , interlude-l >= 0.1.0.6 , monad-control == 1.0.* , transformers-base == 0.4.*+ , list-t , lens+ default-extensions: NoImplicitPrelude benchmark bench-effects type: exitcode-stdio-1.0
+ src/Control/Effects/List.hs view
@@ -0,0 +1,60 @@+{-# LANGUAGE ScopedTypeVariables, TypeFamilies, FlexibleContexts #-} +module Control.Effects.List + ( module Control.Effects.List + , module ListT ) where + +import Interlude hiding (toList, traverse_, fold, foldMaybe, splitAt, head) + +import ListT hiding (take) + +import Control.Effects + +data List + +type instance EffectMsg1 List = [] +type instance EffectRes1 List = Identity +type instance EffectCon1 List a = () + +-- | Runs the rest of the computation for every value in the list +choose :: MonadEffect1 List m => [a] -> m a +choose = fmap runIdentity . effect1 (Proxy :: Proxy List) + +-- | Signals that this branch of execution failed to produce a result. +deadEnd :: MonadEffect1 List m => m a +deadEnd = choose [] + +-- | A generic handler for the List effect. Takes a handler for the ListT transformer as a param. +handleList :: Monad m => (ListT m a -> m b) -> EffectHandler1 List (ListT m) a -> m b +handleList f = f . handleEffect1 (fmap Identity . fromFoldable) + +-- | Execute all the effects and collect the result in a list. +-- Note that this forces all the results, no matter which elements of the result list you end +-- up actually using. For lazyer behavior use the other handlers. +evaluateToList :: Monad m => EffectHandler1 List (ListT m) a -> m [a] +evaluateToList = handleList toList + +-- | Given a function, apply it to all the results. +traverseAllResults :: Monad m => (a -> m ()) -> EffectHandler1 List (ListT m) a -> m () +traverseAllResults handler = handleList (traverse_ handler) + +-- | Given a folding function, fold over every result. If you want to terminate eary, use the +-- `foldWithEarlyTermination` instead. +foldAllResults :: Monad m => (r -> a -> m r) -> r -> EffectHandler1 List (ListT m) a -> m r +foldAllResults f i = handleList (fold f i) + +-- | Same as `foldAllResults` but the folding function has the ability to terminate eary by +-- returning Nothing. +foldWithEarlyTermination :: Monad m => (r -> a -> m (Maybe r)) -> r + -> EffectHandler1 List (ListT m) a -> m r +foldWithEarlyTermination f i = handleList (foldMaybe f i) + +-- | Executes only the effects needed to produce the first n results. +evaluateNResults :: Monad m => Int -> EffectHandler1 List (ListT m) a -> m [a] +evaluateNResults n = handleList (fmap fst . splitAt n) + +-- | Executes only the effects needed to produce a single result. +evaluateOneResult :: Monad m => EffectHandler1 List (ListT m) a -> m (Maybe a) +evaluateOneResult = handleList head + +test :: IO (Maybe Int) +test = evaluateOneResult (return 1)
src/Control/Effects1.hs view
@@ -11,7 +11,7 @@ type family EffectMsg1 eff :: * -> * type family EffectRes1 eff :: * -> * -type family EffectCon1 eff :: * -> Constraint +type family EffectCon1 eff a :: Constraint class Monad m => MonadEffect1 eff m where -- | Use the effect described by 'eff'.