packages feed

explicit-sharing 0.7 → 0.8

raw patch · 8 files changed

+249/−19 lines, 8 filesdep ~derivedep ~mtldep ~template-haskellPVP ok

version bump matches the API change (PVP)

Dependency ranges changed: derive, mtl, template-haskell

API changes (from Hackage documentation)

- Control.Monad.Sharing.Classes: instance (Monad m) => Convertible m Bool Bool
- Control.Monad.Sharing.Classes: instance (Monad m) => Convertible m Char Char
- Control.Monad.Sharing.Classes: instance (Monad m) => Convertible m Int Int
- Control.Monad.Sharing.Classes: instance (Monad m) => Convertible m [Bool] [Bool]
- Control.Monad.Sharing.Classes: instance (Monad m) => Convertible m [Char] [Char]
- Control.Monad.Sharing.Classes: instance (Monad m) => Convertible m [Int] [Int]
- Control.Monad.Sharing.Classes: instance (Monad m) => Shareable m (a -> b)
- Control.Monad.Sharing.Classes: instance (Monad m) => Shareable m Bool
- Control.Monad.Sharing.Classes: instance (Monad m) => Shareable m Char
- Control.Monad.Sharing.Classes: instance (Monad m) => Shareable m Int
- Control.Monad.Sharing.Classes: instance (Monad m) => Shareable m [Bool]
- Control.Monad.Sharing.Classes: instance (Monad m) => Shareable m [Char]
- Control.Monad.Sharing.Classes: instance (Monad m) => Shareable m [Int]
- Data.Monadic.Derive: makeConvertible :: Derivation
- Data.Monadic.Derive: makeMData :: Derivation
- Data.Monadic.Derive: makeShareable :: Derivation
+ Control.Monad.Sharing: runSharing :: MonadPlus m => (forall s. (MonadPlus s, Sharing s) => s a) -> m a
+ Control.Monad.Sharing.Classes: instance Monad m => Convertible m Bool Bool
+ Control.Monad.Sharing.Classes: instance Monad m => Convertible m Char Char
+ Control.Monad.Sharing.Classes: instance Monad m => Convertible m Double Double
+ Control.Monad.Sharing.Classes: instance Monad m => Convertible m Float Float
+ Control.Monad.Sharing.Classes: instance Monad m => Convertible m Int Int
+ Control.Monad.Sharing.Classes: instance Monad m => Convertible m Integer Integer
+ Control.Monad.Sharing.Classes: instance Monad m => Convertible m [Bool] [Bool]
+ Control.Monad.Sharing.Classes: instance Monad m => Convertible m [Char] [Char]
+ Control.Monad.Sharing.Classes: instance Monad m => Convertible m [Double] [Double]
+ Control.Monad.Sharing.Classes: instance Monad m => Convertible m [Float] [Float]
+ Control.Monad.Sharing.Classes: instance Monad m => Convertible m [Int] [Int]
+ Control.Monad.Sharing.Classes: instance Monad m => Convertible m [Integer] [Integer]
+ Control.Monad.Sharing.Classes: instance Monad m => Shareable m (a -> b)
+ Control.Monad.Sharing.Classes: instance Monad m => Shareable m Bool
+ Control.Monad.Sharing.Classes: instance Monad m => Shareable m Char
+ Control.Monad.Sharing.Classes: instance Monad m => Shareable m Double
+ Control.Monad.Sharing.Classes: instance Monad m => Shareable m Float
+ Control.Monad.Sharing.Classes: instance Monad m => Shareable m Int
+ Control.Monad.Sharing.Classes: instance Monad m => Shareable m Integer
+ Control.Monad.Sharing.Classes: instance Monad m => Shareable m [Bool]
+ Control.Monad.Sharing.Classes: instance Monad m => Shareable m [Char]
+ Control.Monad.Sharing.Classes: instance Monad m => Shareable m [Double]
+ Control.Monad.Sharing.Classes: instance Monad m => Shareable m [Float]
+ Control.Monad.Sharing.Classes: instance Monad m => Shareable m [Int]
+ Control.Monad.Sharing.Classes: instance Monad m => Shareable m [Integer]
+ Data.Monadic.Derive: convertible :: Derivation
+ Data.Monadic.Derive: derive :: Derivation -> Name -> Q [Dec]
+ Data.Monadic.Derive: mdata :: Derivation
+ Data.Monadic.Derive: shareable :: Derivation
- Control.Monad.Sharing: convert :: (Convertible m a b) => a -> m b
+ Control.Monad.Sharing: convert :: Convertible m a b => a -> m b
- Control.Monad.Sharing: shareArgs :: (Shareable m a, Monad n) => (forall b. (Shareable m b) => m b -> n (m b)) -> a -> n a
+ Control.Monad.Sharing: shareArgs :: (Shareable m a, Monad n) => (forall b. Shareable m b => m b -> n (m b)) -> a -> n a
- Control.Monad.Sharing.Classes: convert :: (Convertible m a b) => a -> m b
+ Control.Monad.Sharing.Classes: convert :: Convertible m a b => a -> m b
- Control.Monad.Sharing.Classes: shareArgs :: (Shareable m a, Monad n) => (forall b. (Shareable m b) => m b -> n (m b)) -> a -> n a
+ Control.Monad.Sharing.Classes: shareArgs :: (Shareable m a, Monad n) => (forall b. Shareable m b => m b -> n (m b)) -> a -> n a
- Control.Monad.Sharing.FirstOrder: convert :: (Convertible m a b) => a -> m b
+ Control.Monad.Sharing.FirstOrder: convert :: Convertible m a b => a -> m b
- Control.Monad.Sharing.FirstOrder: shareArgs :: (Shareable m a, Monad n) => (forall b. (Shareable m b) => m b -> n (m b)) -> a -> n a
+ Control.Monad.Sharing.FirstOrder: shareArgs :: (Shareable m a, Monad n) => (forall b. Shareable m b => m b -> n (m b)) -> a -> n a
- Data.Monadic.List: cons :: (Monad m) => m a -> m (List m a) -> m (List m a)
+ Data.Monadic.List: cons :: Monad m => m a -> m (List m a) -> m (List m a)
- Data.Monadic.List: first :: (MonadPlus m) => m (List m a) -> m a
+ Data.Monadic.List: first :: MonadPlus m => m (List m a) -> m a
- Data.Monadic.List: isEmpty :: (Monad m) => m (List m a) -> m Bool
+ Data.Monadic.List: isEmpty :: Monad m => m (List m a) -> m Bool
- Data.Monadic.List: nil :: (Monad m) => m (List m a)
+ Data.Monadic.List: nil :: Monad m => m (List m a)
- Data.Monadic.List: rest :: (MonadPlus m) => m (List m a) -> m (List m a)
+ Data.Monadic.List: rest :: MonadPlus m => m (List m a) -> m (List m a)

Files

Control/Monad/Sharing.hs view
@@ -18,7 +18,7 @@    -- * Monad transformer -  Lazy, evalLazy+  Lazy, evalLazy, runSharing   ) where 
Control/Monad/Sharing/Classes.hs view
@@ -61,6 +61,18 @@  where   shareArgs _ = return +instance Monad m => Shareable m Integer+ where+  shareArgs _ = return++instance Monad m => Shareable m Float+ where+  shareArgs _ = return++instance Monad m => Shareable m Double+ where+  shareArgs _ = return+ instance Monad m => Shareable m Char  where   shareArgs _ = return@@ -73,6 +85,18 @@  where   shareArgs _ = return +instance Monad m => Shareable m [Integer]+ where+  shareArgs _ = return++instance Monad m => Shareable m [Float]+ where+  shareArgs _ = return++instance Monad m => Shareable m [Double]+ where+  shareArgs _ = return+ instance Monad m => Shareable m [Char]  where   shareArgs _ = return@@ -108,6 +132,18 @@  where   convert = return +instance Monad m => Convertible m Integer Integer+ where+  convert = return++instance Monad m => Convertible m Float Float+ where+  convert = return++instance Monad m => Convertible m Double Double+ where+  convert = return+ instance Monad m => Convertible m Char Char  where   convert = return@@ -117,6 +153,18 @@   convert = return  instance Monad m => Convertible m [Int] [Int]+ where+  convert = return++instance Monad m => Convertible m [Integer] [Integer]+ where+  convert = return++instance Monad m => Convertible m [Float] [Float]+ where+  convert = return++instance Monad m => Convertible m [Double] [Double]  where   convert = return 
Control/Monad/Sharing/Implementation/CPS.hs view
@@ -19,7 +19,7 @@ -- performance. module Control.Monad.Sharing.Implementation.CPS ( -  Lazy, evalLazy, runLazy,+  Lazy, runLazy, evalLazy, runSharing,    Store, emptyStore, freshLabel, lookupValue, storeValue, @@ -52,17 +52,23 @@   fromLazy :: forall w . (a -> Store -> m w) -> Store -> m w  } +runSharing :: MonadPlus m => (forall s.(MonadPlus s,Sharing s) => s a) -> m a+runSharing a = runLazy a+ -- | -- Lifts all monadic effects to the top-level and unwraps the monad -- transformer for explicit sharing. evalLazy :: (Monad m, Convertible (Lazy m) a b) => Lazy m a -> m b evalLazy m = runLazy (m >>= convert)+{-# DEPRECATED evalLazy "Please use runSharing instead" #-}  -- private declarations  runLazy :: Monad m => Lazy m a -> m a runLazy m = fromLazy m (\a _ -> return a) emptyStore-  -- fromLazy m (\a s -> trace (show (nextLabel s)) (return a)) emptyStore+--   fromLazy m+--     (\a s -> trace ("used refs: "++show (nextLabel s-1)) (return a))+--     emptyStore  -- Stores consist of a fresh-reference counter and a heap represented -- as IntMap.
Data/Monadic/Derive.hs view
@@ -8,11 +8,15 @@ -- Automatic deriving of monadic data types and corresponding instances. module Data.Monadic.Derive ( -  monadic, makeMData, makeShareable, makeConvertible+  derive, +  monadic, mdata, shareable, convertible+   ) where  import Language.Haskell++import Data.DeriveTH ( derive ) import Data.Derive.Internal.Derivation  import Control.Monad.Error@@ -48,7 +52,7 @@ -- > $(derive monadic ''Maybe) --  monadic :: Derivation-monadic = derivationCustom "Monadic"+monadic = derivationCustom "monadic"             (\ (_,d) -> concat <$> mapM ($d) [convData,shareableInst,convInsts])  -- | Generates a monadic datatype and corresponding con- and@@ -60,7 +64,7 @@ --  --   can be translated into its monadic counterpart by typing -- --- > $(derive makeMData ''Maybe)+-- > $(derive mdata ''Maybe) --  --   This call generates the following datatype -- @@ -78,14 +82,14 @@ -- > matchMMaybe :: Monad m => m (MMaybe m a) -> m b -> (m a -> m b) -> m b -- > matchMMaybe x n j = x >>= \x -> case x of { MNothing -> n; MJust a -> j a } -- -makeMData :: Derivation-makeMData = derivationCustom "MData" (convData . snd)+mdata :: Derivation+mdata = derivationCustom "mdata" (convData . snd)  -- | Generates a 'Shareable' instance for a monadic datatype. --  --   For example the call -- --- > $(derive makeShareable ''Maybe)+-- > $(derive shareable ''Maybe) --  --   generates the following instance: -- @@ -93,15 +97,15 @@ -- >   shareArgs fun MNothing  = return MNothing -- >   shareArgs fun (MJust a) = fun a >>= \a -> mJust a -- -makeShareable :: Derivation-makeShareable = derivationCustom "Shareable" (shareableInst . snd)+shareable :: Derivation+shareable = derivationCustom "shareable" (shareableInst . snd)  -- | Generates 'Convertible' instances to convert between monadic and --   non-monadic datatypes. --  --   For example, the call -- --- > $(derive makeConvertible ''Maybe)+-- > $(derive convertible ''Maybe) --  --   generates the following instances: -- @@ -115,8 +119,8 @@ -- >   convArgs fun MNothing  = return Nothing -- >   convArgs fun (MJust a) = (a >>= fun) >>= \a -> return (Just a) -- -makeConvertible :: Derivation-makeConvertible = derivationCustom "Convertible" (convInsts . snd)+convertible :: Derivation+convertible = derivationCustom "convertible" (convInsts . snd)  -- printDecls (Left s) = Left s -- printDecls (Right ds) = trace (unlines . map prettyPrint $ ds) (Right ds)
explicit-sharing.cabal view
@@ -1,5 +1,5 @@ Name:          explicit-sharing-Version:       0.7+Version:       0.8 Cabal-Version: >= 1.6 Synopsis:      Explicit Sharing of Monadic Effects Description:   @@ -17,12 +17,12 @@ Build-Type:    Custom Stability:     experimental -Extra-Source-Files: Test.hs+Extra-Source-Files: Test.hs, permsort.hs, reverse.hs, last.hs  Library-  Build-Depends:    base >= 3 && < 5, containers, mtl,-                    template-haskell >= 2.4 && < 2.5,-                    derive >= 2.3.0.1 && < 2.4+  Build-Depends:    base >= 3 && < 5, containers, mtl < 2,+                    template-haskell >= 2.4 && < 2.6,+                    derive >= 2.3.0.1 && < 2.5   Exposed-Modules:  Control.Monad.Sharing,                     Control.Monad.Sharing.Classes,                     Control.Monad.Sharing.FirstOrder,
+ last.hs view
@@ -0,0 +1,57 @@+{-# LANGUAGE NoMonomorphismRestriction #-}++-- to compile, run:+-- ghc -O2 --make last++-- $ time ./last 1000000 +RTS -H1000M -K20M+-- True+-- user	0m1.154s++-- $ time ./last 10000000 +RTS -H1000M -K20M+-- True+-- user	0m9.263s++-- $ time ./last.mcc 1000000 +RTS -h1000m -k20m+-- 1000000+-- user	0m6.370s++-- $ time ./last.mcc 10000000 +RTS -h2000m -k50m+-- Not enough free memory after garbage collection++import Control.Monad.Sharing+import Data.Monadic.List+import System ( getArgs )++import Prelude hiding ( last )++main =+ do n <- liftM (read.head) getArgs+    let result = runSharing(last(convert(replicate n True))>>=convert)::[Bool]+    mapM_ print result++last :: (MonadPlus m, Sharing m) => m (List m Bool) -> m Bool+last l = do x <- share freeBool+            l =:= append freeBoolList (cons x nil)+            x++append :: Monad m => m (List m a) -> m (List m a) -> m (List m a)+append mxs ys = do xs <- mxs; appendLists xs ys++appendLists :: Monad m => List m a -> m (List m a) -> m (List m a)+appendLists Nil         ys = ys+appendLists (Cons x xs) ys = cons x (append xs ys)++freeBool :: MonadPlus m => m Bool+freeBool = return False `mplus` return True++freeBoolList :: MonadPlus m => m (List m Bool)+freeBoolList = nil `mplus` cons freeBool freeBoolList++(=:=) :: MonadPlus m => m (List m Bool) -> m (List m Bool) -> m ()+mxs =:= mys = do xs <- mxs; ys <- mys; eqBoolList xs ys++eqBoolList :: MonadPlus m => List m Bool -> List m Bool -> m ()+eqBoolList Nil         Nil         = return ()+eqBoolList (Cons x xs) (Cons y ys) = do True <- liftM2 (==) x y+                                        xs =:= ys+eqBoolList _           _           = mzero
+ permsort.hs view
@@ -0,0 +1,66 @@+{-# LANGUAGE NoMonomorphismRestriction #-}++-- to compile, run:+-- ghc -O2 --make permsort.hs++-- $ time ./permsort 20+-- user	0m8.909s++-- time ./permsort.mcc 20+-- user	0m25.067s++-- Comparing different implementations using GHC 6.12.1++-- standard StateT with unevaluated thunks in store+-- user	1m41.645s++-- continition monad with unevaluated thunks in store+-- user	0m37.073s++-- continuation monad with fewer store operations+-- user	0m29.517s++-- additionally with hand optimized memo function+-- user	0m8.909s+++import Control.Monad.Sharing+import Data.Monadic.List++import System ( getArgs )++main = do+  n <- liftM (read.head) getArgs+  let result = runSharing (sort (convert [(1::Int)..n]) >>= convert) :: [[Int]]+  mapM_ print result++++perm :: MonadPlus m => List m a -> m (List m a)+perm Nil         = nil+perm (Cons x xs) = insert x (perm =<< xs)++insert :: MonadPlus m => m a -> m (List m a) -> m (List m a)+insert e l = cons e l+     `mplus` do+        Cons x xs <- l+        cons x (insert e xs)++sort :: (MonadPlus m, Sharing m) => m (List m Int) -> m (List m Int)+sort l = do+  xs <- share (perm =<< l)+  True <- isSorted =<< xs+  xs++isSorted :: Monad m => List m Int -> m Bool+isSorted Nil           = return True+isSorted (Cons mx mxs) = isSorted' mx =<< mxs++isSorted' :: Monad m => m Int -> List m Int -> m Bool+isSorted' _  Nil           = return True+isSorted' mx (Cons my mys) = do+  x <- mx+  y <- my+  if x <= y+   then isSorted' (return y) =<< mys+   else return False
+ reverse.hs view
@@ -0,0 +1,49 @@+{-# LANGUAGE NoMonomorphismRestriction #-}++-- naive reverse to compare performance of purely functional programs+-- with monadic deterministic programs.++-- to compile, run:+-- ghc -O2 -o reverse.mon --make reverse.hs++-- $ time ./reverse.fun 20000+-- user	0m8.804s++-- $ time ./reverse.mon 20000+-- user	0m10.522s++-- $ time ./reverse.mcc 20000+-- user	0m14.530s+++import Control.Monad.Sharing+import Data.Monadic.List++import System ( getArgs )++main = main_mon++main_fun =+ do n <- liftM (read.head) getArgs+    print . length . rev $ [1..n]++rev []     = []+rev (x:xs) = rev xs ++ [x]++main_mon =+ do n <- liftM (read.head) getArgs+    let result =+          runSharing(convert=<<(length'=<<rev'=<<convert[(1::Int)..n]))::[Int]+    mapM_ print result++length' :: Monad m => List m a -> m Int+length' Nil         = return 0+length' (Cons _ xs) = liftM succ (length' =<< xs)++rev' :: Monad m => List m Int -> m (List m Int)+rev' Nil         = nil+rev' (Cons x xs) = (`append`cons x nil) =<< rev' =<< xs++append :: Monad m => List m a -> m (List m a) -> m (List m a)+append Nil         ys = ys+append (Cons x xs) ys = cons x (xs >>= (`append`ys))