packages feed

contstuff 0.1.0 → 0.2.0

raw patch · 3 files changed

+152/−9 lines, 3 filesnew-component:exe:testPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

+ Control.ContStuff: ChoiceT :: ((i -> a -> (i -> m r) -> m r) -> i -> (i -> m r) -> m r) -> ChoiceT r i m a
+ Control.ContStuff: callCC :: (CallCC m) => ((a -> m b) -> m a) -> m a
+ Control.ContStuff: class CallCC m
+ Control.ContStuff: data Label m a
+ Control.ContStuff: findAll :: (Alternative f, Applicative m) => ChoiceT (f a) (f a) m a -> m (f a)
+ Control.ContStuff: findFirst :: (Alternative f, Applicative m) => ChoiceT (f a) (f a) m a -> m (f a)
+ Control.ContStuff: getChoiceT :: ChoiceT r i m a -> (i -> a -> (i -> m r) -> m r) -> i -> (i -> m r) -> m r
+ Control.ContStuff: goto :: (Applicative m) => Label m a -> a -> m b
+ Control.ContStuff: instance (LiftBase m a, Monad m) => LiftBase (ChoiceT r i m) a
+ Control.ContStuff: instance (Monad m, Stateful m) => Stateful (ContT r m)
+ Control.ContStuff: instance Alternative (ChoiceT r i m)
+ Control.ContStuff: instance Applicative (ChoiceT r i m)
+ Control.ContStuff: instance CallCC (ContT r m)
+ Control.ContStuff: instance CallCC (StateT r s m)
+ Control.ContStuff: instance Functor (ChoiceT r i m)
+ Control.ContStuff: instance Monad (ChoiceT r i m)
+ Control.ContStuff: instance Transformer (ChoiceT r i)
+ Control.ContStuff: labelCC :: (Applicative m, CallCC m) => a -> m (a, Label m a)
+ Control.ContStuff: listA :: (Alternative f) => [a] -> f a
+ Control.ContStuff: listChoiceT :: (Applicative m) => ChoiceT [a] [a] m a -> m [a]
+ Control.ContStuff: newtype ChoiceT r i m a
+ Control.ContStuff: runChoiceT :: (i -> a -> (i -> m r) -> m r) -> i -> (i -> m r) -> ChoiceT r i m a -> m r

Files

Control/ContStuff.hs view
@@ -24,6 +24,9 @@     Cont, runCont, evalCont, modifyCont,     ContT(..), runContT, evalContT, modifyContT,     -- ** Advanced CPS monads+    -- *** Choice/nondeterminism+    ChoiceT(..), runChoiceT, findFirst, findAll, listChoiceT, listA,+    -- *** State     State, runState, evalState, execState,     StateT(..), runStateT, evalStateT, execStateT,     -- ** Writer monads@@ -33,6 +36,7 @@      -- * Effect classes     Abortable(..),+    CallCC(..), Label, labelCC, goto,     LiftBase(..), io,     Runnable(..),     Stateful(..), getField, modify, modifyField, modifyFieldLazy, modifyLazy,@@ -83,6 +87,85 @@ -- ================== --  +-------------+-- ChoiceT --+-------------++-- | The choice monad transformer, which models, as the most common+-- interpretation, nondeterminism.  Internally a list of choices is+-- represented as a CPS-based left-fold function.++newtype ChoiceT r i m a =+  ChoiceT { getChoiceT ::+              (i -> a -> (i -> m r) -> m r)+                -> i+                -> (i -> m r)+                -> m r }+++instance Alternative (ChoiceT r i m) where+  empty = ChoiceT $ \_ z k -> k z+  ChoiceT c <|> ChoiceT d =+    ChoiceT $ \fold z k ->+      c fold z (\zc -> d fold zc k)++instance Applicative (ChoiceT r i m) where+  pure x = ChoiceT $ \fold z k -> fold z x k+  ChoiceT cf <*> ChoiceT cx =+    ChoiceT $ \fold z k ->+      cx (\xx yx kx -> cf (\xf yf kf -> fold xf (yf yx) kf) xx kx) z k++instance Functor (ChoiceT r i m) where+  fmap f (ChoiceT c) =+    ChoiceT $ \fold z k ->+      c (\x y k -> fold x (f y) k) z k++instance Monad (ChoiceT r i m) where+  return x = ChoiceT $ \fold z k -> fold z x k+  ChoiceT c >>= f =+    ChoiceT $ \fold z k ->+      c (\x y kc -> getChoiceT (f y) fold x kc) z k++instance Transformer (ChoiceT r i) where+  lift c = ChoiceT $ \fold z k -> c >>= \x -> fold z x k+++-- | Run a choice computation.++runChoiceT ::+  (i -> a -> (i -> m r) -> m r)+    -> i+    -> (i -> m r)+    -> ChoiceT r i m a+    -> m r+runChoiceT fold z k (ChoiceT c) = c fold z k+++-- | Find the first solution.++findFirst :: (Alternative f, Applicative m) => ChoiceT (f a) (f a) m a -> m (f a)+findFirst = runChoiceT (\_ y _ -> pure (pure y)) empty pure+++-- | Find all solutions.++findAll :: (Alternative f, Applicative m) => ChoiceT (f a) (f a) m a -> m (f a)+findAll = runChoiceT (\x y k -> k (x <|> pure y)) empty pure+++-- | Get list of solutions (faster than 'findAll', but returns solutions+-- in reversed order).++listChoiceT :: Applicative m => ChoiceT [a] [a] m a -> m [a]+listChoiceT = runChoiceT (\x y k -> k (y:x)) [] pure+++-- | Turn a list into a computation with alternatives.++listA :: Alternative f => [a] -> f a+listA = foldr (<|>) empty . map pure++ ----------- -- ContT -- -----------@@ -107,6 +190,9 @@   ContT cf <*> ContT cx =     ContT $ \k -> cf (\f -> cx (\x -> k (f x))) +instance CallCC (ContT r m) where+  callCC f = ContT $ \k -> getContT (f (ContT . const . k)) k+ instance Functor (ContT r m) where   fmap f (ContT c) = ContT $ \k -> c (\x -> k (f x)) @@ -278,6 +364,9 @@   StateT cf <*> StateT cx =     StateT $ \s0 k -> cf s0 (\s1 f -> cx s1 (\s2 x -> k s2 (f x))) +instance CallCC (StateT r s m) where+  callCC f = StateT $ \s0 k -> getStateT (f (\x -> StateT $ \s1 _ -> k s1 x)) s0 k+ instance Functor (StateT r s m) where   fmap f (StateT c) =     StateT $ \s0 k -> c s0 (\s1 -> k s1 . f)@@ -375,6 +464,28 @@   abort :: Result m -> m a  +-- | Monads supporting *call-with-current-continuation* (aka callCC).++class CallCC m where+  -- | Call with current continuation.+  callCC :: ((a -> m b) -> m a) -> m a+++newtype Label m a = Label (a -> Label m a -> m ())+++-- | Capture the current continuation for later use.++labelCC :: (Applicative m, CallCC m) => a -> m (a, Label m a)+labelCC x = callCC $ \k -> pure (x, Label $ curry k)+++-- | Jump to a label.++goto :: Applicative m => Label m a -> a -> m b+goto lk@(Label k) x = k x lk *> pure undefined++ -- | Monads, which support lifting base monad computations.  class LiftBase m a where@@ -390,6 +501,8 @@  instance (LiftBase m a, Monad m) => LiftBase (IdT m) a where   type Base (IdT m) a = Base m a; base = lift . base+instance (LiftBase m a, Monad m) => LiftBase (ChoiceT r i m) a where+  type Base (ChoiceT r i m) a = Base m a; base = lift . base instance (LiftBase m a, Monad m) => LiftBase (ContT r m) a where   type Base (ContT r m) a = Base m a; base = lift . base instance (LiftBase m a, Monad m) => LiftBase (StateT r s m) a where@@ -403,7 +516,7 @@   -- | Every monad transformer @t@ that supports transforming @t m a@ to--- @m a@ should be an instance of this class.+-- @m a@ can be an instance of this class.  class Runnable t r m a where   type Argument t r m a@@ -421,6 +534,12 @@   put x = x `seq` putLazy x   -- | Set the current state, but don't force it.   putLazy :: StateOf m -> m ()++instance (Monad m, Stateful m) => Stateful (ContT r m) where+  type StateOf (ContT r m) = StateOf m+  get = lift get+  put = lift . put+  putLazy = lift . putLazy   -- | Get a certain field.
+ Test.hs view
@@ -0,0 +1,24 @@+-- |+-- Module:     Main+-- Copyright:  (c) 2010 Ertugrul Soeylemez+-- License:    BSD3+-- Maintainer: Ertugrul Soeylemez <es@ertes.de>+-- Stability:  experimental+--+-- This is a test program to test the various monads found in the+-- contstuff library.++module Main where++import Control.ContStuff+import Text.Printf+++main :: IO ()+main =+  evalContT $ do+    (x, begin) <- labelCC 0+    when (mod x 100000 == 0) . io $ do+      putStr (show x)+      putChar '\r'+    goto begin (x+1)
contstuff.cabal view
@@ -1,5 +1,5 @@ Name:          contstuff-Version:       0.1.0+Version:       0.2.0 Category:      Control, Monads Synopsis:      Easy to use CPS-based monads Maintainer:    Ertugrul Söylemez <es@ertes.de>@@ -24,10 +24,10 @@   Exposed-modules:     Control.ContStuff ---Executable test---  Build-depends:---    base >= 4 && <= 5---  Main-is:        Test.hs---  GHC-Options:    -W---  Other-modules:---    Control.ContStuff+Executable test+  Build-depends:+    base >= 4 && <= 5+  Main-is:        Test.hs+  GHC-Options:    -W+  Other-modules:+    Control.ContStuff