packages feed

MonadStack (empty) → 0.1.0.1

raw patch · 5 files changed

+134/−0 lines, 5 filesdep +basedep +mtlsetup-changed

Dependencies added: base, mtl

Files

+ LICENSE view
@@ -0,0 +1,24 @@+Copyright (c) 2015, bhurt+All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++* Redistributions of source code must retain the above copyright notice, this+  list of conditions and the following disclaimer.++* Redistributions in binary form must reproduce the above copyright notice,+  this list of conditions and the following disclaimer in the documentation+  and/or other materials provided with the distribution.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.+
+ MonadStack.cabal view
@@ -0,0 +1,26 @@+-- Initial MonadStack.cabal generated by cabal init.  For further +-- documentation, see http://haskell.org/cabal/users-guide/++name:                MonadStack+version:             0.1.0.1+synopsis:            Generalizing lift to monad stacks+-- description:         +homepage:            https://github.com/bhurt/MonadStack+license:             BSD2+license-file:        LICENSE+author:              Brian Hurt+maintainer:          bhurt42@gmail.com+-- copyright:           +category:            Control+build-type:          Simple+extra-source-files:  README.md+cabal-version:       >=1.10++library+  exposed-modules:     Control.Monad.MonadStack+  -- other-modules:       +  -- other-extensions:    +  build-depends:       base >=4.8 && <4.9,+                       mtl >= 2.2 && <2.3+  hs-source-dirs:      src+  default-language:    Haskell2010
+ README.md view
@@ -0,0 +1,2 @@+# MonadStack+Allow lifting from any level in a monad transformer stack up to any higher level.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ src/Control/Monad/MonadStack.hs view
@@ -0,0 +1,80 @@+{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances #-}++{- |+Module: Control.Monad.MonadStack+Description: A multi-level lift through a monad transformer stack.+Copyright: (C) 2015 by Brian Hurt+License: BSD 2-Clause+Maintainer: Brian Hurt <bhurt42@gmail.com>+Stability: experimental+Portability: safe++MonadStack provides a multi-level @lift@ function, called @liftFrom@.+It allows lifting from an arbitrary monad in a monad transformer stack+up to any higher monad in that stack.  And example use might be:++>    newtype MyMonad = MyMonad ... deriving (Monad)+>+>    doFoo :: MonadStack MyMonad m => something -> m whatever+>    doFoo arg = liftFrom go+>        where+>            go :: MyMonad whatever+>            go = do ...++This allows calling doFoo either in the MyMonad monad, or in any monad+transformer stack on top of the MyMonad.++MonadStack is similar to the @Control.Monad.Base@ module from the+<https://hackage.haskell.org/package/transformers-base transformers-base>+package, except that there is no functional dependency between the+monads.  A monad transformer stack can only have one base, but it can+have several MonadStack implementations.++MonadStack is very similar to the @Control.Monad.Lifter@ module from the+<https://hackage.haskell.org/package/MonadCompose MonadCompose> package,+with two exceptions.  One, MonadStack does not require the+OverlappingInstances and UndecidableInstances extensions- both of which+are prone to generating hard to diagnose bugs.  But this implies two,+that MonadStack is much less feature-rich than Lifter is.  Specifically,+MonadStack only works with "proper" monad transformers (those that+implment @MonadTrans@), while Lifter generalizes the notion of lifting+and works with more different types of monads, especially @MonadPlus@.++-}+module Control.Monad.MonadStack where++    import Control.Monad.Trans++    -- | A multi-level lifter class.+    --+    -- The existance of an implementation of @MonadStack m n@ implies+    -- that is is possible to convert an @m a@ into an @n a@ via+    -- zero or more applications of @lift@.+    class MonadStack m n where+        liftFrom :: m a -> n a++    -- | The base case implementation+    --+    -- You can always convert an @m a@ into an @m a@ by applying 0+    -- lifts.  This is like treating an @m a@ as a zero-level monad+    -- transformer stack (a monad transformer stack with no monad+    -- transformers), and @liftFrom@ is just the @id@ function.+    instance MonadStack m m where+        liftFrom = id++    -- | The inductive step implementation+    --+    -- If there exists an implementation of @MonadStack k m@ for+    -- monads @k@ and @m@ (that is, we can perform a @liftFrom@ to+    -- convert a @k a@ to a @m a@), and n is a monad transformer,+    -- then we can construct an implementation of @MonadStack k (n m)@,+    -- by just adding one more @lift@ to the @liftFrom@.++    -- Conceptually, if I can get from a k a to an m a via some+    -- sequence of lifts, and n is a monad transformer, then I can+    -- get from a k a to a n m a with one more lift.  Or, if I can+    -- lift through an @n@-level monad transformer stack, I can+    -- lift through a @n+1@ level monad transformer stack.+    instance (Monad k, Monad m, MonadTrans n, MonadStack k m)+                    => MonadStack k (n m) where+        liftFrom = lift . liftFrom