lgtk 0.3.2 → 0.4
raw patch · 11 files changed
+115/−101 lines, 11 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
- Control.MLens.ExtRef: class NewRef m => ExtRef m
- Control.MLens.ExtRef: extRef :: ExtRef m => Ref m b -> MLens m a b -> a -> m (Ref m a)
- Control.MLens.ExtRef: undoTr :: ExtRef m => (a -> a -> Bool) -> Ref m a -> m (m (Maybe (m ())), m (Maybe (m ())))
- Control.MLens.ExtRef.Pure: data Ext i m a
- Control.MLens.ExtRef.Pure: instance Functor m => Functor (Ext i m)
- Control.MLens.ExtRef.Pure: instance Monad m => ExtRef (Ext i m)
- Control.MLens.ExtRef.Pure: instance Monad m => Monad (Ext i m)
- Control.MLens.ExtRef.Pure: instance Monad m => NewRef (Ext i m)
- Control.MLens.ExtRef.Pure: instance MonadTrans (Ext i)
- Control.MLens.ExtRef.Pure: instance MonadWriter w m => MonadWriter w (Ext i m)
- Control.MLens.ExtRef.Pure: runExt :: Monad m => (forall i. Ext i m a) -> m a
- Control.MLens.ExtRef.Pure: runExt_ :: (Functor m, NewRef m) => (forall n. (Monad n, Functor n) => Morph m n -> Morph n m -> c n -> c m) -> (forall i. c (Ext i m)) -> m (c m)
- Control.MLens.ExtRef.Pure.Test: instance ExtRef (E i)
- Control.MLens.ExtRef.Pure.Test: instance Monad (E i)
- Control.MLens.ExtRef.Pure.Test: instance MonadWriter [String] (E i)
- Control.MLens.ExtRef.Pure.Test: instance NewRef (E i)
- Control.MLens.ExtRef.Pure.Test: tests :: [String]
- Control.MLens.ExtRef.Test: (==>) :: (Eq a, Show a, MonadWriter [String] m) => Ref m a -> a -> m ()
- Control.MLens.ExtRef.Test: (==?) :: (Eq a, Show a, MonadWriter [String] m) => a -> a -> m ()
- Control.MLens.ExtRef.Test: instance ExtRef m => ExtRef (F m i)
- Control.MLens.ExtRef.Test: instance Monad m => Monad (F m i)
- Control.MLens.ExtRef.Test: instance MonadWriter w m => MonadWriter w (F m i)
- Control.MLens.ExtRef.Test: instance NewRef m => NewRef (F m i)
- Control.MLens.ExtRef.Test: mkTests :: ((forall i. (MonadWriter [String] (m i), ExtRef (m i)) => m i ()) -> [String]) -> [String]
- Control.MLens.ExtRef.Test: mkTests' :: (MonadWriter [String] m, ExtRef m) => (m () -> [String]) -> [String]
- Control.MLens.NewRef: class Monad m => NewRef m
- Control.MLens.NewRef: instance (NewRef m, Monoid w) => NewRef (WriterT w m)
- Control.MLens.NewRef: memoMLens :: (NewRef m, Eq a, Eq b) => MLens m a b -> m (MLens m a b)
- Control.MLens.NewRef: memoRead :: NewRef m => m a -> m (m a)
- Control.MLens.NewRef: memoWrite :: (NewRef m, Eq b) => (b -> m a) -> m (b -> m a)
- Control.MLens.NewRef: newRef :: NewRef m => a -> m (Ref m a)
- Control.MLens.NewRef.Unsafe: instance NewRef IO
- Data.MLens: (***) :: Monad m => MLens m a b -> MLens m c d -> MLens m (a, c) (b, d)
- Data.MLens: MLens :: (a -> m (b, b -> m a)) -> MLens m a b
- Data.MLens: forkLens :: (Monoid a, Monad m) => MLens m a (a, a)
- Data.MLens: fromLens :: Monad m => Lens a b -> MLens m a b
- Data.MLens: fstLens :: Monad m => MLens m (a, b) a
- Data.MLens: getL :: Monad m => MLens m a b -> a -> m b
- Data.MLens: instance Monad m => Category (MLens m)
- Data.MLens: ithLens :: Monad m => Int -> MLens m [a] a
- Data.MLens: joinLens :: Monad m => MLens m a (MLens m a b) -> MLens m a b
- Data.MLens: joinML :: Monad m => (a -> m (MLens m a b)) -> MLens m a b
- Data.MLens: justLens :: Monad m => a -> MLens m (Maybe a) a
- Data.MLens: lens :: Monad m => (a -> b) -> (b -> a -> a) -> MLens m a b
- Data.MLens: lensStore :: Monad m => (a -> (b, b -> a)) -> MLens m a b
- Data.MLens: listLens :: Monad m => MLens m (Bool, (a, [a])) [a]
- Data.MLens: mapMLens :: (Monad m, Monad n) => Morph m n -> MLens m a b -> MLens n a b
- Data.MLens: maybeLens :: Monad m => MLens m (Bool, a) (Maybe a)
- Data.MLens: modL :: Monad m => MLens m b a -> (a -> a) -> b -> m b
- Data.MLens: newtype MLens m a b
- Data.MLens: setL :: Monad m => MLens m a b -> b -> a -> m a
- Data.MLens: showLens :: (Monad m, Show a, Read a) => MLens m a String
- Data.MLens: sndLens :: Monad m => MLens m (a, b) b
- Data.MLens: toLens :: (forall m. Monad m => MLens m a b) -> Lens a b
- Data.MLens: type Lens a b = MLens Identity a b
- Data.MLens: type Morph m n = forall a. m a -> n a
- Data.MLens: unitLens :: Monad m => MLens m a ()
- Data.MLens.Ref: data Unit
- Data.MLens.Ref: fileRef :: FilePath -> IO (Ref IO String)
- Data.MLens.Ref: fileRef_ :: FilePath -> IO (Ref IO (Maybe String))
- Data.MLens.Ref: instance Eq Unit
- Data.MLens.Ref: instance Show Unit
- Data.MLens.Ref: logConsoleLens :: Show a => MLens IO a a
- Data.MLens.Ref: logFile :: FilePath -> IO (String -> IO ())
- Data.MLens.Ref: logMLens :: Monad m => (a -> m ()) -> (a -> m ()) -> MLens m a a
- Data.MLens.Ref: modRef :: Monad m => Ref m a -> (a -> a) -> m ()
- Data.MLens.Ref: readRef :: Monad m => Ref m a -> m a
- Data.MLens.Ref: type Ref m a = MLens m Unit a
- Data.MLens.Ref: writeRef :: Monad m => Ref m a -> a -> m ()
+ Control.MLens: instance ExtRef (ExtTest i)
+ Control.MLens: instance Monad (ExtTest i)
+ Control.MLens: instance MonadWriter [String] (ExtTest i)
+ Control.MLens: instance NewRef (ExtTest i)
+ Control.MLens: runMLens :: MLens m a b -> a -> m (b, b -> m a)
+ Control.MLens: runRef :: Monad m => Ref m a -> m (a, a -> m ())
+ Control.MLens: testExt :: [String]
+ Control.MLens.Unsafe: fileRef :: FilePath -> IO (Ref IO String)
+ Control.MLens.Unsafe: fileRef_ :: FilePath -> IO (Ref IO (Maybe String))
+ Control.MLens.Unsafe: logConsoleLens :: Show a => MLens IO a a
+ Control.MLens.Unsafe: logFile :: FilePath -> IO (String -> IO ())
+ Control.MLens.Unsafe: logMLens :: Monad m => (a -> m ()) -> (a -> m ()) -> MLens m a a
Files
- lgtk.cabal +13/−12
- main/Main.hs +1/−1
- src/Control/MLens.hs +26/−11
- src/Control/MLens/ExtRef.hs +9/−11
- src/Control/MLens/ExtRef/Pure/Test.hs +0/−19
- src/Control/MLens/NewRef.hs +1/−1
- src/Control/MLens/Unsafe.hs +15/−0
- src/Data/MLens.hs +25/−26
- src/Data/MLens/Ref.hs +23/−18
- src/GUI/MLens/Gtk/IO.hs +1/−1
- src/GUI/MLens/Gtk/Interface.hs +1/−1
lgtk.cabal view
@@ -1,9 +1,9 @@ name: lgtk-version: 0.3.2+version: 0.4 category: GUI-synopsis: lens-based GUI with Gtk backend+synopsis: lens-based API for Gtk description:- The main interface of LGtk is "GUI.MLens.Gtk".+ The main interface module of LGtk is "GUI.MLens.Gtk". . See also <http://people.inf.elte.hu/divip/LGtk/index.html> stability: experimental@@ -30,16 +30,8 @@ , gtk exposed-modules:- Data.MLens- Data.MLens.Ref-- Control.MLens.NewRef- Control.MLens.NewRef.Unsafe- Control.MLens.ExtRef- Control.MLens.ExtRef.Test- Control.MLens.ExtRef.Pure- Control.MLens.ExtRef.Pure.Test Control.MLens+ Control.MLens.Unsafe GUI.MLens.Gtk GUI.MLens.Gtk.ADTEditor@@ -48,6 +40,15 @@ GUI.MLens.Gtk.Demos.IntListEditor GUI.MLens.Gtk.Demos.TEditor other-modules:+ Data.MLens+ Data.MLens.Ref++ Control.MLens.NewRef+ Control.MLens.NewRef.Unsafe+ Control.MLens.ExtRef+ Control.MLens.ExtRef.Pure+ Control.MLens.ExtRef.Test+ GUI.MLens.Gtk.IO GUI.MLens.Gtk.Interface ghc-options:
main/Main.hs view
@@ -1,7 +1,7 @@ import Control.Monad import Control.Monad.Trans -import Data.MLens.Ref (fileRef)+import Control.MLens.Unsafe (fileRef) import GUI.MLens.Gtk import GUI.MLens.Gtk.Demos.Tri
src/Control/MLens.hs view
@@ -1,16 +1,10 @@--- {-# LANGUAGE ExistentialQuantification #-}--- {-# LANGUAGE RankNTypes #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-} -- | The main monadic lens interface, ideally users should import only this module. module Control.MLens ( -- * Data types MLens- , Lens , Ref - -- * Lens operations- , getL, setL, modL- , readRef, writeRef, modRef- -- * Lens transformations , mapMLens , (.)@@ -18,14 +12,22 @@ , joinML , memoMLens - -- * Lens creation+ -- * Lens destruction+ , runMLens+ , runRef++ -- * Lens construction , lensStore , NewRef (..) , ExtRef (..) , Ext, runExt, runExt_ -- * Derived constructs- -- ** Pure lenses, built with @lensStore@+ -- ** Lens operations+ , getL, setL, modL+ , readRef, writeRef, modRef++ -- ** Pure lenses, defined with @lensStore@ , id , unitLens , fstLens, sndLens@@ -33,15 +35,16 @@ , listLens , ithLens - -- ** Impure lenses, built with @lensStore@+ -- ** Impure lenses, defined with @lensStore@ , forkLens , justLens , showLens -- ** Other derived construts- , lens+ , Lens , fromLens , toLens+ , lens , joinLens , undoTr , memoRead@@ -49,14 +52,26 @@ -- * Auxiliary definitions , Morph++ -- ** Consistency tests+ , testExt ) where import Control.Category+import Control.Monad.Writer import Prelude hiding ((.), id) import Data.MLens import Data.MLens.Ref import Control.MLens.ExtRef+import Control.MLens.ExtRef.Test import Control.MLens.ExtRef.Pure++newtype ExtTest i a = ExtTest { unExtTest :: Ext i (Writer [String]) a }+ deriving (Monad, MonadWriter [String], NewRef, ExtRef)++-- | Consistency tests for @Ext@, should give an empty list of errors.+testExt :: [String]+testExt = mkTests (\t -> execWriter $ runExt $ unExtTest t)
src/Control/MLens/ExtRef.hs view
@@ -17,27 +17,25 @@ import Data.MLens.Ref {- |-Suppose that @k@ is a pure lens, and--@s <- extRef r k a0@.+Suppose that @r@ is a pure reference and @k@ is a pure lens. The following laws should hold: - * @s@ is a pure reference.+ * @(extRef r k a0 >>= readRef)@ === @(readRef r >>= setL k a0)@ - * @(k . s)@ behaves exactly as @r@.+ * @(extRef r k a0 >> readRef r)@ === @(readRef r)@ - * The initial value of @s@ is the result of @(readRef r >>= setL k a0)@.+Given @s <- extRef r k a0@, the following laws should hold: -Moreover, @(extRef r k a0)@ should not change the value of @r@.+ * @s@ is a pure reference -The following two operations should be identical:+ * @(k . s)@ === @r@ -@newRew x@+Law for @newRef@ when @extRef@ is defined: -@extRef unitLens unitLens x@+ * @(newRew x)@ === @(extRef unitLens unitLens x)@ -For examples, see "Control.MLens.ExtRef.Pure.Test".+For basic usage examples, look into the source of "Control.MLens.ExtRef.Pure.Test". -} class NewRef m => ExtRef m where extRef :: Ref m b -> MLens m a b -> a -> m (Ref m a)
− src/Control/MLens/ExtRef/Pure/Test.hs
@@ -1,19 +0,0 @@-{-# LANGUAGE GeneralizedNewtypeDeriving #-}--- | Tests for the reference implementation of the @ExtRef@ interface.-module Control.MLens.ExtRef.Pure.Test- ( -- * Test suit - tests- ) where--import Control.Monad.Writer--import Control.MLens.ExtRef-import Control.MLens.ExtRef.Test-import Control.MLens.ExtRef.Pure---newtype E i a = E { unE :: Ext i (Writer [String]) a } deriving (Monad, MonadWriter [String], NewRef, ExtRef)--tests :: [String]-tests = mkTests (\t -> execWriter $ runExt $ unE t)-
src/Control/MLens/NewRef.hs view
@@ -19,7 +19,7 @@ {- | Laws for @NewRef@: - * Any reference created by @newRef@ should satisfy the reference laws given in "Data.MLens.Ref".+ * Any reference created by @newRef@ should satisfy the reference laws. -} class (Monad m) => NewRef m where newRef :: a -> m (Ref m a)
+ src/Control/MLens/Unsafe.hs view
@@ -0,0 +1,15 @@+-- | This module exports unsafe definitions, like the @NewRef@ instance for @IO@ which does not fulfil the @NewRef@ laws in a multi-threaded environment.+module Control.MLens.Unsafe+ ( -- * Unsafe references+ fileRef+ , fileRef_+ , logConsoleLens+ , logMLens+ -- * Auxiliary definitions+ , logFile+ ) where++import Data.MLens.Ref+import Control.MLens.NewRef.Unsafe ()++
src/Data/MLens.hs view
@@ -1,7 +1,7 @@ {-# LANGUAGE RankNTypes #-} module Data.MLens ( -- * Monadic lenses data type- MLens (MLens)+ MLens (..) -- * Side-effect free lenses , Lens@@ -46,16 +46,15 @@ {-| Monadic lenses. -The following representations would be also good for @(MLens m a b)@:+Laws for pure monadic lenses: - * @a -> m (Store b (m a))@+ * set-get: @(setL l b a >>= getL l)@ === @(setL l b a >> return b)@ - * @forall f . Functor f => (b -> m (f (m b))) -> a -> m (f (m a))@+ * get-set: @(getL l a >>= \b -> setL l b a)@ === @(return a)@ - * @(a -> m b, b -> a -> m a)@+ * set-set: @(setL l b a >>= setL l b')@ === @(setL l b' a)@ -The last representation has no efficient composition operation-(the set operation on composition of n lenses use O(n * n) get operations with the last representation).+For example, @fstLens@ and @(fstLens . fstLens)@ fulfil these laws. Using lenses which do not fulfil the lens laws are safe, but one should take extra care when doing program transformations@@ -68,24 +67,26 @@ TODO: List laws, document which laws hold for each lenses. -} newtype MLens m a b- = MLens (a -> m (b, b -> m a))--{-|-Side-effect free lenses.+ = MLens { runMLens :: a -> m (b, b -> m a) }+{-+The following representations would be also good for @(MLens m a b)@: -The following representations would be also good for @(Lens a b)@:+ * @a -> m (Store b (m a))@ - * @forall m . Monad m => MLens m a b@+ * @forall f . Functor f => (b -> m (f (m b))) -> a -> m (f (m a))@ -Laws for pure monadic lenses:+ * @(a -> m b, b -> a -> m a)@ - * set-get: @(setL l b a >>= getL l)@ === @(setL l b a >> return b)@+The last representation has no efficient composition operation+(the set operation on composition of n lenses use O(n * n) get operations with the last representation).+-} - * get-set: @(getL l a >>= \b -> setL l b a)@ === @(return a)@+{-|+Side-effect free lenses. - * set-set: @(setL l b a >>= setL l b')@ === @(setL l b' a)@+The following representations would be also good for @(Lens a b)@: -For example, @fstLens@ and @(fstLens . fstLens)@ fulfil these laws.+ * @forall m . Monad m => MLens m a b@ -} type Lens a b = MLens Identity a b@@ -101,19 +102,19 @@ lensStore f = MLens $ return . g . f where g (b, ba) = (b, return . ba) --- | Impure (but effect-free) lens constuctor, built on @lensStore@.+-- | Impure (but effect-free) lens constuctor, defined with @lensStore@. lens :: Monad m => (a -> b) -> (b -> a -> a) -> MLens m a b lens get set = lensStore $ \a -> (get a, flip set a) getL :: Monad m => MLens m a b -> a -> m b-getL (MLens f) a = f a >>= return . fst+getL k a = runMLens k a >>= return . fst setL :: Monad m => MLens m a b -> b -> a -> m a-setL (MLens f) b a = f a >>= ($ b) . snd+setL k b a = runMLens k a >>= ($ b) . snd modL :: Monad m => MLens m b a -> (a -> a) -> b -> m b-modL (MLens g) f b = do- (x, h) <- g b+modL k f b = do+ (x, h) <- runMLens k b h (f x) instance Monad m => Category (MLens m) where@@ -147,9 +148,7 @@ return (x, f . s) joinML :: Monad m => (a -> m (MLens m a b)) -> MLens m a b-joinML r = MLens $ \x -> do- MLens q <- r x- q x+joinML r = MLens $ \x -> r x >>= ($ x) . runMLens -- | It would be possible to define a @Monad@ instance for @(MLens m a)@ too, but monad laws would not hold. joinLens :: Monad m => MLens m a (MLens m a b) -> MLens m a b
src/Data/MLens/Ref.hs view
@@ -6,6 +6,7 @@ , Ref -- * Reference operations+ , runRef , readRef, writeRef, modRef -- * Some impure @IO@ referenceses@@ -31,16 +32,7 @@ data Unit = Unit deriving (Eq, Show) {- |-Note that references lenses can be composed with lenses.-For example, if--@r :: Ref m (a,b)@--then--@fstLens . r :: Ref m a@--Reference laws for pure references:+Laws for pure references: * @(readRef r >> return ())@ === @(return ())@ @@ -51,17 +43,30 @@ * @(writeRef r a >> writeRef r a')@ === @(writeRef r a')@ These laws are equivalent to the get-no-effect, set-get, get-set and set-set laws for monadic lenses.++Reference lenses can be composed with lenses.+For example, if++@r :: Ref m (a,b)@++then++@fstLens . r :: Ref m a@ -} type Ref m a = MLens m Unit a +runRef :: Monad m => Ref m a -> m (a, a -> m ())+runRef r = liftM f $ runMLens r Unit where+ f (a, m) = (a, \a -> m a >> return ())+ readRef :: Monad m => Ref m a -> m a-readRef k = getL k Unit+readRef = liftM fst . runRef writeRef :: Monad m => Ref m a -> a -> m ()-writeRef r a = setL r a Unit >> return ()+writeRef r a = runRef r >>= ($ a) . snd modRef :: Monad m => Ref m a -> (a -> a) -> m ()-k `modRef` f = modL k f Unit >> return ()+k `modRef` f = runRef k >>= \(a, m) -> m $ f a -- | Using @fileRef@ is safe if the file is not used concurrently. fileRef :: FilePath -> IO (Ref IO String)@@ -69,16 +74,16 @@ -- | Note that if you write @Nothing@, the file is deleted. fileRef_ :: FilePath -> IO (Ref IO (Maybe String))-fileRef_ f = return $ MLens $ \Unit -> do+fileRef_ f = return $ MLens $ \unit -> do b <- doesFileExist f if b then do xs <- readFile f- length xs `seq` return (Just xs, wr)- else return (Nothing, wr)+ length xs `seq` return (Just xs, wr unit)+ else return (Nothing, wr unit) where- wr mb = do+ wr unit mb = do maybe (doesFileExist f >>= \b -> when b (removeFile f)) (writeFile f) mb- return Unit+ return unit logMLens :: Monad m => (a -> m ()) -> (a -> m ()) -> MLens m a a logMLens getLog setLog = MLens $ \a -> getLog a >> return (a, \b -> setLog b >> return b)
src/GUI/MLens/Gtk/IO.hs view
@@ -13,7 +13,7 @@ import Graphics.UI.Gtk import Control.MLens-import Control.MLens.NewRef.Unsafe ()+import Control.MLens.Unsafe () import GUI.MLens.Gtk.Interface ------------------
src/GUI/MLens/Gtk/Interface.hs view
@@ -7,7 +7,7 @@ import Control.Monad.Free -import Data.MLens.Ref+import Control.MLens -- | Interface description parametrized by a monad data I m