monad-primitive (empty) → 0.1
raw patch · 5 files changed
+219/−0 lines, 5 filesdep +basedep +primitivedep +transformerssetup-changed
Dependencies added: base, primitive, transformers
Files
- Control/Monad/Primitive/Class.hs +94/−0
- Data/PrimRef.hs +64/−0
- LICENSE +30/−0
- Setup.hs +2/−0
- monad-primitive.cabal +29/−0
+ Control/Monad/Primitive/Class.hs view
@@ -0,0 +1,94 @@+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE FlexibleContexts #-}+-- |+-- Module : Control.Monad.Primitive.Class+-- Copyright : (c) 2013 Aleksey Khudyakov+-- License : BSD3+--+-- Maintainer : alexey.skladnoy@gmail.com+-- Stability : experimental+-- Portability : non-portable+module Control.Monad.Primitive.Class (+ MonadPrim(..)+ ) where++import Control.Monad.ST (ST)+import Control.Monad.Primitive (PrimMonad)+import Control.Monad.Trans.Class (lift)+import Data.Monoid (Monoid)++import Control.Monad.Trans.Cont (ContT)+import Control.Monad.Trans.Error (ErrorT,Error)+import Control.Monad.Trans.Identity (IdentityT)+import Control.Monad.Trans.Maybe (MaybeT)+import Control.Monad.Trans.Reader (ReaderT)+import Control.Monad.Trans.RWS.Strict as S (RWST)+import Control.Monad.Trans.RWS.Lazy as L (RWST)+import Control.Monad.Trans.State.Strict as S (StateT)+import Control.Monad.Trans.State.Lazy as L (StateT)+import Control.Monad.Trans.Writer.Strict as S (WriterT)+import Control.Monad.Trans.Writer.Lazy as L (WriterT)+++-- | Monads in which computation based on primitive monad (instance of+-- 'PrimMonad') could be embedded. Instances must obey following laws:+--+-- > liftPrim . return = return+-- > liftPrim (m >>= f) = liftPrim m >>= liftPrim f+class (PrimMonad (BasePrimMonad m), Monad m) => MonadPrim m where+ type BasePrimMonad m :: * -> *+ liftPrim :: BasePrimMonad m a -> m a++++instance MonadPrim IO where+ type BasePrimMonad IO = IO+ liftPrim = id++instance MonadPrim (ST s) where+ type BasePrimMonad (ST s) = (ST s)+ liftPrim = id++instance MonadPrim m => MonadPrim (ContT r m) where+ type BasePrimMonad (ContT r m) = BasePrimMonad m+ liftPrim = lift . liftPrim++instance (MonadPrim m, Error e) => MonadPrim (ErrorT e m) where+ type BasePrimMonad (ErrorT e m) = BasePrimMonad m+ liftPrim = lift . liftPrim++instance MonadPrim m => MonadPrim (IdentityT m) where+ type BasePrimMonad (IdentityT m) = BasePrimMonad m+ liftPrim = lift . liftPrim++instance MonadPrim m => MonadPrim (MaybeT m) where+ type BasePrimMonad (MaybeT m) = BasePrimMonad m+ liftPrim = lift . liftPrim++instance MonadPrim m => MonadPrim (ReaderT r m) where+ type BasePrimMonad (ReaderT r m) = BasePrimMonad m+ liftPrim = lift . liftPrim++instance (MonadPrim m, Monoid w) => MonadPrim (S.RWST r w s m) where+ type BasePrimMonad (S.RWST r w s m) = BasePrimMonad m+ liftPrim = lift . liftPrim++instance (MonadPrim m, Monoid w) => MonadPrim (L.RWST r w s m) where+ type BasePrimMonad (L.RWST r w s m) = BasePrimMonad m+ liftPrim = lift . liftPrim++instance MonadPrim m => MonadPrim (S.StateT s m) where+ type BasePrimMonad (S.StateT s m) = BasePrimMonad m+ liftPrim = lift . liftPrim++instance MonadPrim m => MonadPrim (L.StateT s m) where+ type BasePrimMonad (L.StateT s m) = BasePrimMonad m+ liftPrim = lift . liftPrim++instance (MonadPrim m, Monoid w) => MonadPrim (S.WriterT w m) where+ type BasePrimMonad (S.WriterT w m) = BasePrimMonad m+ liftPrim = lift . liftPrim++instance (MonadPrim m, Monoid w) => MonadPrim (L.WriterT w m) where+ type BasePrimMonad (L.WriterT w m) = BasePrimMonad m+ liftPrim = lift . liftPrim
+ Data/PrimRef.hs view
@@ -0,0 +1,64 @@+{-# LANGUAGE MagicHash #-}+{-# LANGUAGE UnboxedTuples #-}+{-# LANGUAGE NoImplicitPrelude #-}+-- |+-- Module : Data.PrimRef+-- Copyright : (c) 2013 Aleksey Khudyakov+-- License : BSD3+--+-- Maintainer : alexey.skladnoy@gmail.com+-- Stability : experimental+-- Portability : portable+--+-- Mutable references in monads which are instances of 'MonadPrim'.+module Data.PrimRef (+ -- * PrimRefs+ PrimRef+ , newPrimRef+ , readPrimRef+ , writePrimRef+ , modifyPrimRef+ , modifyPrimRef'+ ) where++import Control.Monad.Primitive (PrimMonad(..))+import GHC.Base (MutVar#,newMutVar#,readMutVar#,writeMutVar#)+import Prelude (($),($!))+++-- | Mutable variable which full analog of 'Data.IORef.IORef' or+-- 'Data.STRef.STRef' but could use either of the monads.+-- Unfortunately there's no way to convert @PrimRef@ to @STRef@ or+-- @IORef@.+data PrimRef m a = PrimRef (MutVar# (PrimState m) a)++-- | Create new mutable variable with initial value @a@.+newPrimRef :: PrimMonad m => a -> m (PrimRef m a)+newPrimRef a = primitive $ \s1# ->+ case newMutVar# a s1# of+ (# s2#, var# #) -> (# s2#, PrimRef var# #)++-- | Read value of @PrimRef@.+readPrimRef :: PrimMonad m => PrimRef m a -> m a+readPrimRef (PrimRef var#)+ = primitive $ \s1# -> readMutVar# var# s1#++-- | Write value to @PrimRef@.+writePrimRef :: PrimMonad m => PrimRef m a -> a -> m ()+writePrimRef (PrimRef var#) a+ = primitive $ \s1# ->+ case writeMutVar# var# a s1# of+ s2# -> (# s2#, () #)++-- | Modify content of @PrimRef@ using function.+modifyPrimRef :: PrimMonad m => PrimRef m a -> (a -> a) -> m ()+modifyPrimRef var f = do+ x <- readPrimRef var+ writePrimRef var $ f x++-- | Modify content of @PrimRef@ using function and evaluate result of+-- function application to WHNF before storing it in the variable.+modifyPrimRef' :: PrimMonad m => PrimRef m a -> (a -> a) -> m ()+modifyPrimRef' var f = do+ x <- readPrimRef var+ writePrimRef var $! f x
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright (c) Aleksey Khudyakov++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions+are met:++1. Redistributions of source code must retain the above copyright+ notice, this list of conditions and the following disclaimer.++2. 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.++3. Neither the name of the author nor the names of his contributors+ may be used to endorse or promote products derived from this software+ without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE 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 AUTHORS 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
+ monad-primitive.cabal view
@@ -0,0 +1,29 @@+Name: monad-primitive+Version: 0.1+Synopsis: Type class for monad transformers stack with pirimitive base monad.+Description:+ Type class for for monad transformers stack with pirimitive base+ monad and mutable references whic could use either ST or IO monads.++Cabal-Version: >= 1.6+License: BSD3+License-File: LICENSE+Author: Aleksey Khudyakov <alexey.skladnoy@gmail.com>+Maintainer: Aleksey Khudyakov <alexey.skladnoy@gmail.com>+Homepage: http://bitbucket.org/Shimuuar/monad-primitive+Category: Data+Build-Type: Simple++source-repository head+ type: hg+ location: http://bitbucket.org/Shimuuar/monad-primitive++Library+ Ghc-options: -Wall+ Build-Depends:+ base >=3 && <5,+ transformers >=0.3,+ primitive+ Exposed-modules:+ Control.Monad.Primitive.Class+ Data.PrimRef