packages feed

has-transformers (empty) → 0.1.0.0

raw patch · 13 files changed

+290/−0 lines, 13 filesdep +basedep +has-transformersdep +hspec

Dependencies added: base, has-transformers, hspec, operational, transformers

Files

+ CHANGELOG.md view
@@ -0,0 +1,5 @@+# Revision history for lift-transformers++## 0.1.0.0 -- YYYY-mm-dd++* First version. Released on an unsuspecting world.
+ LICENSE view
@@ -0,0 +1,20 @@+Copyright (c) 2021 Manuel Bärenz++Permission is hereby granted, free of charge, to any person obtaining+a copy of this software and associated documentation files (the+"Software"), to deal in the Software without restriction, including+without limitation the rights to use, copy, modify, merge, publish,+distribute, sublicense, and/or sell copies of the Software, and to+permit persons to whom the Software is furnished to do so, subject to+the following conditions:++The above copyright notice and this permission notice shall be included+in all copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ examples/Examples/StateSig.hs view
@@ -0,0 +1,35 @@+module Examples.StateSig where++import "base" Control.Monad (when)++import "operational" Control.Monad.Operational++import "has-transformers" Control.Monad.Trans.Has+import "has-transformers" Control.Monad.Trans.Has.State++data StateSig s a where+  Put :: s -> StateSig s ()+  Get :: StateSig s s++type StateSigT s m a = ProgramT (StateSig s) m a++type HasStateSig s m = Has (ProgramT (StateSig s)) m++putS :: HasStateSig s m => s -> m ()+-- putS = liftH . singleton . Put+putS s = liftH $ singleton $ Put s++getS :: HasStateSig s m => m s+getS = liftH $ singleton Get++program :: (HasStateSig Bool m, Monad m) => m ()+program = do+  b <- getS+  when b $ putS False++interpretStateSig :: HasState s m => StateSig s a -> m a+interpretStateSig (Put s) = put s+interpretStateSig Get = get++interpretStateSigT :: (HasState s m, Monad m) => StateSigT s m a -> m a+interpretStateSigT = interpretWithMonadT interpretStateSig
+ examples/Examples/TwoReaders.hs view
@@ -0,0 +1,30 @@+module Examples.TwoReaders where++import "has-transformers" Control.Monad.Trans.Has.Reader++-- | Our "business logic" program using two 'ReaderT' effects.+--   Note that we use a type signature to help the type checker understand+--   which environment is which.+program ::+  (Monad m, HasReader Int m, HasReader Bool m) =>+  m (Int, Bool)+program = do+  envInt <- ask+  envBool <- ask+  return (envInt, envBool)++-- | The 'Int' environment we are going to supply+envInt :: Int+envInt = 23++-- | The 'Bool' environment we are going to supply+envBool :: Bool+envBool = True++-- | For documentation, this is the stack that will be handled.+--   (But we don't actually ever use this type alias.)+type Stack a = ReaderT Int (ReaderT Bool IO) a++-- | The 'program' with its environments supplied+handled :: IO (Int, Bool)+handled = program `runReaderT` envInt `runReaderT` envBool
+ examples/Examples/TwoReadersSpec.hs view
@@ -0,0 +1,11 @@+module Examples.TwoReadersSpec where++import "hspec" Test.Hspec++import Examples.TwoReaders++spec :: Spec+spec = do+  describe "two-Reader stack" $ do+    it "returns the environments" $ do+      handled `shouldReturn` (envInt, envBool)
+ examples/Spec.hs view
@@ -0,0 +1,1 @@+{-# OPTIONS_GHC -F -pgmF hspec-discover #-}
+ has-transformers.cabal view
@@ -0,0 +1,65 @@+cabal-version:      2.4+name:               has-transformers+version:            0.1.0.0++synopsis: This library `Has` transformers++description:+  A very slim library for first-order effects based on monad transformers+  (and nearly nothing else).+  .+  Given a transformer stack @t1 (t2 (t3 (... m))) a@,+  you can automatically lift any function @thing :: tN m a@ into the stack with a single function, 'liftH'.++bug-reports: https://github.com/turion/has-transformers/issues+license: MIT+license-file: LICENSE+author: Manuel Bärenz+maintainer: programming@manuelbaerenz.de++copyright: (c) 2021- Manuel Bärenz+category: Effect+extra-source-files: CHANGELOG.md++library+  exposed-modules:+    Control.Monad.Trans.Has+    Control.Monad.Trans.Has.Accum+    Control.Monad.Trans.Has.Except+    Control.Monad.Trans.Has.Reader+    Control.Monad.Trans.Has.State+    Control.Monad.Trans.Has.Writer+  default-extensions:+      ConstraintKinds+    , FlexibleContexts+    , FlexibleInstances+    , ImportQualifiedPost+    , MultiParamTypeClasses+    , PackageImports+  build-depends:+      base ^>= 4.14.3.0+    , transformers+  hs-source-dirs: src+  default-language: Haskell2010++test-suite examples+  type: exitcode-stdio-1.0+  default-language: Haskell2010+  main-is: Spec.hs+  hs-source-dirs: examples+  other-modules:+    Examples.StateSig+    Examples.TwoReaders+    Examples.TwoReadersSpec+  default-extensions:+      ConstraintKinds+    , FlexibleContexts+    , GADTs+    , ImportQualifiedPost+    , PackageImports+  build-depends:+      base ^>= 4.14.3.0+    , has-transformers+    , hspec >= 2.9.0+    , operational+  build-tool-depends: hspec-discover:hspec-discover
+ src/Control/Monad/Trans/Has.hs view
@@ -0,0 +1,36 @@+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE KindSignatures #-}+module Control.Monad.Trans.Has where++import "transformers" Control.Monad.Trans.Class++-- |+-- class Has t m where+--   liftH :: t Identity a -> m a++{- | The transformer stack @m@ contains the transformer @t@.++Explicitly, @m = t1 (t2 (t3 ... (tN m)...))@,+and @t@ is one of these @t1, t2, ...@s.+-}+class Has (t :: (* -> *) -> * -> *) m where+  {- | Insert an action of this transformer into an arbitrary position in the stack.++  This will apply 'lift' as many times as necessary to insert the action.+  The higher-rank type involving @forall n@ basically says:+  "The action to lift must only use the structure of the _transformer_,+  not of a specific monad,+  and is thus definable for any monad @n@".+  -}+  liftH :: (forall n . Monad n => t n a) -> m a++-- | If the transformer is outermost,+--   the action can be inserted as-is.+instance Monad m => Has t (t m) where+  liftH = id+  {-# INLINE liftH #-}++-- | If the target transformer @t@ is under a different layer @t1@, 'lift' once.+instance {-# Overlappable #-} (Monad m, MonadTrans t1, Has t m) => Has t (t1 m) where+  liftH action = lift $ liftH action+  {-# INLINE liftH #-}
+ src/Control/Monad/Trans/Has/Accum.hs view
@@ -0,0 +1,17 @@+module Control.Monad.Trans.Has.Accum+  ( module Control.Monad.Trans.Has.Accum+  , module X+  ) where++import "transformers" Control.Monad.Trans.Accum+  qualified as Accum+import "transformers" Control.Monad.Trans.Accum+  as X+  (AccumT (..))++import "this" Control.Monad.Trans.Has++type HasAccum w m = Has (AccumT w) m++add :: HasAccum w m => w -> m ()+add w = liftH $ Accum.add w
+ src/Control/Monad/Trans/Has/Except.hs view
@@ -0,0 +1,18 @@+module Control.Monad.Trans.Has.Except+  ( module Control.Monad.Trans.Has.Except+  , module X+  ) where++import "transformers" Control.Monad.Trans.Except+  qualified as Except+import "transformers" Control.Monad.Trans.Except+  as X+  (ExceptT (..))++import "this" Control.Monad.Trans.Has+import qualified Control.Monad.Trans.Except as Control.Monad.Trans.Has++type HasExcept e m = Has (ExceptT e) m++throw :: HasExcept e m => e -> m ()+throw e = liftH $ ExceptT $ return $ Left e
+ src/Control/Monad/Trans/Has/Reader.hs view
@@ -0,0 +1,16 @@+module Control.Monad.Trans.Has.Reader+  ( module Control.Monad.Trans.Has.Reader+  , module X+  ) where++import "transformers" Control.Monad.Trans.Reader+  qualified as Reader+import "transformers" Control.Monad.Trans.Reader+  as X (ReaderT(..))++import "this" Control.Monad.Trans.Has++type HasReader r m = Has (ReaderT r) m++ask :: HasReader r m => m r+ask = liftH Reader.ask
+ src/Control/Monad/Trans/Has/State.hs view
@@ -0,0 +1,19 @@+module Control.Monad.Trans.Has.State+  ( module Control.Monad.Trans.Has.State+  , module X+  ) where++import "transformers" Control.Monad.Trans.State.Strict+  qualified as State+import "transformers" Control.Monad.Trans.State.Strict+  as X (StateT(..))++import "this" Control.Monad.Trans.Has++type HasState s m = Has (StateT s) m++get :: HasState s m => m s+get = liftH State.get++put :: HasState s m => s -> m ()+put s = liftH $ State.put s
+ src/Control/Monad/Trans/Has/Writer.hs view
@@ -0,0 +1,17 @@+module Control.Monad.Trans.Has.Writer+  ( module Control.Monad.Trans.Has.Writer+  , module X+  ) where++import "transformers" Control.Monad.Trans.Writer.Strict+  qualified as Writer+import "transformers" Control.Monad.Trans.Writer.Strict+  as X+  (WriterT (..))++import "this" Control.Monad.Trans.Has++type HasWriter w m = Has (WriterT w) m++tell :: HasWriter w m => w -> m ()+tell w = liftH $ Writer.tell w