demarcate (empty) → 0.1.0
raw patch · 6 files changed
+182/−0 lines, 6 filesdep +basedep +freedep +hspecsetup-changed
Dependencies added: base, free, hspec, transformers
Files
- LICENSE +30/−0
- Setup.hs +2/−0
- demarcate.cabal +40/−0
- src/Control/Monad/Trans/Demarcate.hs +23/−0
- src/Control/Monad/Trans/Demarcate/Internal.hs +86/−0
- test/Spec.hs +1/−0
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright (c) 2013, Nickolay Kudasov++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.++ * Neither the name of Nickolay Kudasov nor the names of other+ contributors may be used to endorse or promote products derived+ from this software without specific prior written permission.++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+OWNER 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.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ demarcate.cabal view
@@ -0,0 +1,40 @@+Name: demarcate+Version: 0.1.0+Author: Nickolay Kudasov<nickolay.kudasov@gmail.com>+Maintainer: Nickolay Kudasov<nickolay.kudasov@gmail.com>+License: BSD3+License-File: LICENSE+Synopsis: Demarcating transformed monad.+Description:+ This library provides 'Demarcate' type constructor which makes+ possible transformations of @t m a@ monadic values.+Cabal-Version: >= 1.10+Build-Type: Simple+Stability: experimental+Homepage: https://github.com/fizruk/demarcate+Bug-Reports: https://github.com/fizruk/demarcate/issues+Category: Control++Library+ Default-Language: Haskell2010+ Default-Extensions: Trustworthy+ HS-Source-Dirs: src+ GHC-Options: -Wall+ Exposed-Modules: Control.Monad.Trans.Demarcate+ Control.Monad.Trans.Demarcate.Internal+ Build-Depends: base >= 4 && < 5+ , free >= 3.4.2+ , transformers >= 0.3++Test-Suite spec+ Type: exitcode-stdio-1.0+ Default-Language: Haskell2010+ Hs-Source-Dirs: test+ Ghc-Options: -Wall+ Main-Is: Spec.hs+ Build-Depends: base+ , hspec++Source-Repository head+ Type: git+ Location: https://github.com/fizruk/demarcate.git
+ src/Control/Monad/Trans/Demarcate.hs view
@@ -0,0 +1,23 @@+---------------------------------------------------------------------------+-- | +-- Module : Control.Monad.Trans.Demarcate+-- Copyright : (c) 2013 Nickolay Kudasov+-- License : BSD-style (see the file LICENSE)+-- +-- Maintainer : nickolay.kudasov@gmail.com+-- Stability : experimental+-- Portability : ghc+--+-- Interface for 'Demarcate' monad transformer.+---------------------------------------------------------------------------+module Control.Monad.Trans.Demarcate+(+ Demarcate,+ demarcateM, demarcateT,+ execDemarcate,+ wrapT,+ transformDemarcateM, transformDemarcateFree,+ hoistDemarcateT,+) where++import Control.Monad.Trans.Demarcate.Internal
+ src/Control/Monad/Trans/Demarcate/Internal.hs view
@@ -0,0 +1,86 @@+{-# LANGUAGE Rank2Types #-}+{-# LANGUAGE ExistentialQuantification #-}+{-# LANGUAGE MultiParamTypeClasses #-}+---------------------------------------------------------------------------+-- |+-- Module : Control.Monad.Trans.Demarcate.Internal+-- Copyright : (c) Nickolay Kudasov 2013+-- License : BSD-style (see the file LICENSE)+-- +-- Maintainer : nickolay.kudasov@gmail.com+-- Stability : experimental+-- Portability : ghc+--+-- Internals of the 'Demarcate' monad transformer.+---------------------------------------------------------------------------+module Control.Monad.Trans.Demarcate.Internal where++import Control.Monad.Free+import Control.Monad.Trans.Class+import Control.Monad (join)++-- | Demarcate functor.+data DemarcateF t m next+ = forall a. DemarcateMonad ( m a) (a -> next) -- ^ Unlifted monadic computation.+ | forall a. DemarcateTrans (t m a) (a -> next) -- ^ Transformed monadic computation.++instance Functor (DemarcateF t m) where+ fmap f (DemarcateMonad m g) = DemarcateMonad m (f . g)+ fmap f (DemarcateTrans m g) = DemarcateTrans m (f . g)++-- | Demarcate monad transformer.+newtype Demarcate t m a = Demarcate+ { unDemarcate :: Free (DemarcateF t m) a }++instance Functor (Demarcate t m) where+ fmap f = Demarcate . fmap f . unDemarcate++instance Monad (Demarcate t m) where+ return = Demarcate . return+ m >>= f = Demarcate $ unDemarcate m >>= unDemarcate . f++instance MonadFree (DemarcateF t m) (Demarcate t m) where+ wrap = Demarcate . wrap . fmap unDemarcate++instance MonadTrans (Demarcate t) where+ lift m = liftF $ DemarcateMonad m id++-- | Lift pure monadic computation into @Demarcate t m a@+demarcateM :: m a -> Demarcate t m a+demarcateM m = liftF $ DemarcateMonad m id++-- | Lift transformed monadic computation into @Demarcate t m a@+demarcateT :: t m a -> Demarcate t m a+demarcateT m = liftF $ DemarcateTrans m id++-- | Execute demarcated computation.+execDemarcate :: (Monad (t m), Monad m, MonadTrans t) => Demarcate t m a -> t m a+execDemarcate = iterM execDemarcateF . unDemarcate+ where+ execDemarcateF (DemarcateMonad m next) = lift m >>= next+ execDemarcateF (DemarcateTrans m next) = m >>= next++-- | Subsitute monad transformer.+hoistDemarcateT :: (forall b. t m b -> t' m b) -> Demarcate t m a -> Demarcate t' m a+hoistDemarcateT phi = iterM hoistDemarcateF . unDemarcate+ where+ hoistDemarcateF (DemarcateMonad m next) = demarcateM m >>= next+ hoistDemarcateF (DemarcateTrans m next) = demarcateT (phi m) >>= next++-- | Substitute monad computations with demarcated.+transformDemarcateM :: (forall b. m b -> Demarcate t m b) -> Demarcate t m a -> Demarcate t m a+transformDemarcateM phi = iterM transformF . unDemarcate+ where+ transformF (DemarcateMonad m next) = phi m >>= next+ transformF (DemarcateTrans m next) = demarcateT m >>= next++-- | Substitute free monad actions with demarcated monad computations.+transformDemarcateFree :: (Functor f) =>+ (forall b. f (Demarcate t (Free f) b) -> Demarcate t (Free f) b) -> Demarcate t (Free f) a -> Demarcate t (Free f) a+transformDemarcateFree phi = transformDemarcateM (iterM phi)++-- | Helper function (useful with @transformDemarcateFree@).+-- I believe it should be somewhere in @Control.Monad.Free@+wrapT :: (Functor f, MonadFree f m, MonadTrans t, Monad (t m)) => f (t m a) -> t m a+wrapT = join . lift . liftF+
+ test/Spec.hs view
@@ -0,0 +1,1 @@+{-# OPTIONS_GHC -F -pgmF hspec-discover #-}