Safe Haskell | None |
---|
Main LGtk interface.
- class Category cat where
- class Category c => Tensor c where
- liftM :: Monad m => (a1 -> r) -> m a1 -> m r
- liftM2 :: Monad m => (a1 -> a2 -> r) -> m a1 -> m a2 -> m r
- liftM3 :: Monad m => (a1 -> a2 -> a3 -> r) -> m a1 -> m a2 -> m a3 -> m r
- when :: Monad m => Bool -> m () -> m ()
- newtype Lens a b = Lens {}
- lens :: (a -> b) -> (b -> a -> a) -> Lens a b
- iso :: (a -> b) -> (b -> a) -> Lens a b
- runLens :: Lens a b -> a -> Store b a
- getL :: Lens a b -> a -> b
- setL :: Lens a b -> b -> a -> a
- modL :: Lens a b -> (b -> b) -> a -> a
- fstLens :: Lens (a, b) a
- sndLens :: Lens (a, b) b
- listLens :: Lens (Bool, (a, [a])) [a]
- maybeLens :: Lens (Bool, a) (Maybe a)
- showLens :: (Show a, Read a) => Lens a String
- type Morph m n = forall a. m a -> n a
- class (Monad m, Monad (ReadPart m)) => HasReadPart m where
- type ReadPart m :: * -> *
- liftReadPart :: Morph (ReadPart m) m
- class HasReadPart (RefMonad r) => Reference r where
- type RefMonad r :: * -> *
- readRef :: r a -> ReadRefMonad r a
- writeRef :: r a -> a -> RefMonad r ()
- lensMap :: Lens a b -> r a -> r b
- joinRef :: ReadRefMonad r (r a) -> r a
- unitRef :: r ()
- type ReadRefMonad m = ReadPart (RefMonad m)
- class (Monad m, Reference (Ref m)) => ExtRef m where
- type ReadRef m = ReadRefMonad (Ref m)
- type WriteRef m = RefMonad (Ref m)
- liftReadRef :: ExtRef m => Morph (ReadRef m) m
- modRef :: Reference r => r a -> (a -> a) -> RefMonad r ()
- readRef' :: ExtRef m => Ref m a -> m a
- memoRead :: ExtRef m => m a -> m (m a)
- undoTr :: ExtRef m => (a -> a -> Bool) -> Ref m a -> m (ReadRef m (Maybe (WriteRef m ())), ReadRef m (Maybe (WriteRef m ())))
- data EqRef r a
- eqRef :: (Reference r, Eq a) => r a -> EqRef r a
- toRef :: Reference r => EqRef r a -> r a
- hasEffect :: Reference r => EqRef r a -> (a -> a) -> ReadRefMonad r Bool
- class ExtRef m => EffRef m where
- class Monad m => SafeIO m where
- class (EffRef m, SafeIO m, SafeIO (ReadRef m)) => EffIORef m where
- putStrLn_ :: EffIORef m => String -> m ()
- type Widget m = Widget (EffectM m) m
- runWidget :: (forall m. EffIORef m => Widget m) -> IO ()
- label :: EffRef m => ReadRef m String -> Widget m
- checkbox :: EffRef m => Ref m Bool -> Widget m
- combobox :: EffRef m => [String] -> Ref m Int -> Widget m
- entry :: EffRef m => Ref m String -> Widget m
- vcat :: [Widget m] -> Widget m
- hcat :: [Widget m] -> Widget m
- button_ :: EffRef m => ReadRef m String -> ReadRef m Bool -> WriteRef m () -> Widget m
- data Color = Color Word16 Word16 Word16
- notebook :: EffRef m => [(String, Widget m)] -> Widget m
- cell_ :: (EffRef m, Eq a) => ReadRef m a -> (forall x. (Widget m -> m x) -> a -> m (m x)) -> Widget m
- action :: EffRef m => m (Widget m) -> Widget m
- empty :: Widget m
- entryShow :: (EffRef m, Show a, Read a) => Ref m a -> Widget m
- button :: EffRef m => ReadRef m String -> ReadRef m (Maybe (WriteRef m ())) -> Widget m
- smartButton :: EffRef m => ReadRef m String -> EqRef (Ref m) a -> (a -> a) -> Widget m
- cell :: (EffRef m, Eq a) => ReadRef m a -> (a -> Widget m) -> Widget m
- cellNoMemo :: (EffRef m, Eq a) => ReadRef m a -> (a -> Widget m) -> Widget m
- button__ :: EffRef m => ReadRef m String -> ReadRef m Bool -> ReadRef m Color -> WriteRef m () -> Widget m
Re-export
Category
class Category cat where
A class for categories. id and (.) must form a monoid.
Tensor
Monad
liftM2 :: Monad m => (a1 -> a2 -> r) -> m a1 -> m a2 -> m r
Promote a function to a monad, scanning the monadic arguments from left to right. For example,
liftM2 (+) [0,1] [0,2] = [0,2,1,3] liftM2 (+) (Just 1) Nothing = Nothing
liftM3 :: Monad m => (a1 -> a2 -> a3 -> r) -> m a1 -> m a2 -> m a3 -> m r
Promote a function to a monad, scanning the monadic arguments from
left to right (cf. liftM2
).
when :: Monad m => Bool -> m () -> m ()
Conditional execution of monadic expressions. For example,
when debug (putStr "Debugging\n")
will output the string Debugging\n
if the Boolean value debug
is True
,
and otherwise do nothing.
Lenses
Construction
newtype Lens a b
Deconstruction
Pure lenses
Impure lenses
Monad morphisms
class (Monad m, Monad (ReadPart m)) => HasReadPart m whereSource
m
has a submonad (ReadPart m)
which is isomorphic to Reader
.
type ReadPart m :: * -> *Source
Law: (ReadPart m)
=== (
for some Reader
x)x
.
Alternative laws which ensures this isomorphism (r :: (ReadPart m a)
is arbitrary):
-
(r >> return ())
===return ()
-
liftM2 (,) r r
===liftM (a -> (a, a)) r
See also http://stackoverflow.com/questions/16123588/what-is-this-special-functor-structure-called
liftReadPart :: Morph (ReadPart m) mSource
(ReadPart m)
is a submonad of m
Monad m => HasReadPart (StateT s m) | ReadPart (StateT s m) = Reader s |
References
Basic operations
class HasReadPart (RefMonad r) => Reference r whereSource
A reference (r a)
is isomorphic to (
for some fixed state Lens
s a)s
.
r
=== Lens s
type RefMonad r :: * -> *Source
Refmonad r
=== State s
Property derived from the HasReadPart
instance:
ReadRefMonad r
= ReadPart (Refmonad r)
=== Reader s
readRef :: r a -> ReadRefMonad r aSource
readRef
=== reader . getL
Properties derived from the HasReadPart
instance:
(readRef r >> return ())
=== return ()
writeRef :: r a -> a -> RefMonad r ()Source
writeRef r
=== modify . setL r
Properties derived from the set-get, get-set and set-set laws for lenses:
-
(readRef r >>= writeRef r)
===return ()
-
(writeRef r a >> readRef r)
===return a
-
(writeRef r a >> writeRef r a')
===writeRef r a'
lensMap :: Lens a b -> r a -> r bSource
Apply a lens on a reference.
lensMap
=== (.)
joinRef :: ReadRefMonad r (r a) -> r aSource
joinRef
makes possible to define dynamic references, i.e. references which depends on
values of other references.
It is not possible to create new reference dynamically with joinRef
; for that, see onChange
.
joinRef
=== Lens . join . (runLens .) . runReader
unitRef
=== lens (const ()) (const id)
type ReadRefMonad m = ReadPart (RefMonad m)Source
Reference creation
class (Monad m, Reference (Ref m)) => ExtRef m whereSource
Monad for reference creation. Reference creation is not a method
of the Reference
type class to make possible to
create the same type of references in multiple monads.
(Extref m) === (StateT s m)
, where s
is an extendible state.
For basic usage examples, look into the source of Control.Monad.ExtRef.Pure.Test
.
extRef :: Ref m b -> Lens a b -> a -> m (Ref m a)Source
Reference creation by extending the state of an existing reference.
Suppose that r
is a reference and k
is a lens.
Law 1: extRef
applies k
on r
backwards, i.e.
the result of (extRef r k a0)
should behaves exactly as (lensMap k r)
.
-
(liftM (k .) $ extRef r k a0)
===return r
Law 2: extRef
does not change the value of r
:
-
(extRef r k a0 >> readRef r)
===(readRef r)
Law 3: Proper initialization of newly defined reference with a0
:
-
(extRef r k a0 >>= readRef)
===(readRef r >>= setL k a0)
newRef :: a -> m (Ref m a)Source
newRef
extends the state s
in an independent way.
newRef
=== extRef unitRef (lens (const ()) (const id))
ExtRef m => ExtRef (IdentityT m) | This instance is used in the implementation, end users do not need it. |
(ExtRef m, Monoid w) => ExtRef (WriterT w m) | This instance is used in the implementation, end users do not need it. |
(ExtRef m, Monoid w) => ExtRef (RWST r w s m) | This instance is used in the implementation, end users do not need it. |
type ReadRef m = ReadRefMonad (Ref m)Source
liftReadRef :: ExtRef m => Morph (ReadRef m) mSource
ReadRef
lifted to the reference creation class.
Note that we do not lift WriteRef
to the reference creation class, which a crucial restriction
in the LGtk interface; this is a feature.
Derived constructs
modRef :: Reference r => r a -> (a -> a) -> RefMonad r ()Source
modRef r f
=== liftReadPart (readRef r) >>= writeRef r . f
readRef' :: ExtRef m => Ref m a -> m aSource
readRef
lifted to the reference creation class.
readRef'
=== liftReadRef . readRef
memoRead :: ExtRef m => m a -> m (m a)Source
Lazy monadic evaluation.
In case of y <- memoRead x
, invoking y
will invoke x
at most once.
Laws:
-
(memoRead x >> return ())
===return ()
-
(memoRead x >>= id)
===x
-
(memoRead x >>= y -> liftM2 (,) y y)
===liftM (a -> (a, a)) y
-
(memoRead x >>= y -> liftM3 (,) y y y)
===liftM (a -> (a, a, a)) y
- ...
:: ExtRef m | |
=> (a -> a -> Bool) | equality on state |
-> Ref m a | reference of state |
-> m (ReadRef m (Maybe (WriteRef m ())), ReadRef m (Maybe (WriteRef m ()))) | undo and redo actions |
Undo-redo state transformation.
References with inherent equivalence.
EqRef r a
=== ReadRefMonad r (forall b . Eq b => (Lens b a, r b))
As a reference, (m :: EqRef r a)
behaves as
joinRef $ liftM (uncurry lensMap) m
EqRef
makes defining auto-sensitive buttons easier, see later.
eqRef :: (Reference r, Eq a) => r a -> EqRef r aSource
EqRef
construction.
hasEffect
is correct only if eqRef
is applied on a pure reference (a reference which is a pure lens on the hidden state).
toRef :: Reference r => EqRef r a -> r aSource
An EqRef
is a normal reference if we forget about the equality.
toRef m
=== joinRef $ liftM (uncurry lensMap) m
hasEffect :: Reference r => EqRef r a -> (a -> a) -> ReadRefMonad r BoolSource
hasEffect r f
returns False
iff (modRef m f)
=== (return ())
.
Dynamic networks
class ExtRef m => EffRef m whereSource
Monad for dynamic actions
onChange :: Eq a => Bool -> ReadRef m a -> (a -> m (m ())) -> m ()Source
Let r
be an effectless action (ReadRef
guarantees this).
(onChange init r fmm)
has the following effect:
Whenever the value of r
changes (with respect to the given equality),
fmm
is called with the new value a
.
The value of the (fmm a)
action is memoized,
but the memoized value is run again and again.
The boolean parameter init
tells whether the action should
be run in the beginning or not.
For example, let (k :: a -> m b)
and (h :: b -> m ())
,
and suppose that r
will have values a1
, a2
, a3
= a1
, a4
= a2
.
onChange True r $ \a -> k a >>= return . h
has the effect
k a1 >>= \b1 -> h b1 >> k a2 >>= \b2 -> h b2 >> h b1 >> h b2
and
onChange False r $ \a -> k a >>= return . h
has the effect
k a2 >>= \b2 -> h b2 >> k a1 >>= \b1 -> h b1 >> h b2
I/O
class Monad m => SafeIO m whereSource
Type class for effectless, synchronous IO
actions.
The program's command line arguments (not including the program name).
getProgName :: m StringSource
The name of the program as it was invoked.
lookupEnv :: String -> m (Maybe String)Source
(lookupEnv var)
returns the value of the environment variable var
.
SafeIO IO | This instance is used in the implementation, the end users do not need it. |
SafeIO m => SafeIO (IdentityT m) | This instance is used in the implementation, the end users do not need it. |
(SafeIO m, Monoid w) => SafeIO (RWST r w s m) | This instance is used in the implementation, the end users do not need it. |
class (EffRef m, SafeIO m, SafeIO (ReadRef m)) => EffIORef m whereSource
Type class for IO actions.
asyncWrite :: Eq a => Int -> (a -> WriteRef m ()) -> a -> m ()Source
(asyncWrite t f a)
has the effect of doing (f a)
after waiting t
milliseconds.
Note that (asyncWrite 0 f a)
acts immediately after the completion of the current computation,
so it is safe, because the effect of (f a)
is not interleaved with
the current computation.
Although (asyncWrite 0)
is safe, code using it has a bad small.
fileRef :: FilePath -> m (Ref m (Maybe String))Source
(fileRef path)
returns a reference which holds the actual contents
of the file accessed by path
.
When the value of the reference changes, the file changes. When the file changes, the value of the reference changes.
If the reference holds Nothing
, the file does not exist.
Note that you delete the file by putting Nothing
into the reference.
Implementation note: The references returned by fileRef
are not
memoised so currently it is unsafe to call fileRef
on the same filepath more than once.
This restriction will be lifted in the future.
putStr_ :: String -> m ()Source
Write a string to the standard output device.
getLine_ :: (String -> WriteRef m ()) -> m ()Source
Read a line from the standard input device.
(getLine_ f)
returns immediately. When the line s
is read,
f s
is called.
Derived constructs
GUI
Running
type Widget m = Widget (EffectM m) mSource
Gtk widget descriptions.
Construction of a (w :: forall m . EffIORef m => Widget m)
value is side-effect free,
side-effects happen at running (
.
runWidget
w)
Widget
should be abstract data type, but it is also safe to keep it as a type synonym because
the operations of the revealed implementation are hidden.
runWidget :: (forall m. EffIORef m => Widget m) -> IO ()Source
Run a Gtk widget description.
The widget is shown in a window and the thread enters into the Gtk event cycle. It leaves the event cycle when the window is closed.
GUI descriptions
:: EffRef m | |
=> ReadRef m String | dynamic label of the button |
-> ReadRef m Bool | the button is active when this returns |
-> WriteRef m () | the action to do when the button is pressed |
-> Widget m |
Low-level button.
data Color
Color
- Specifies a color with three integer values for red, green and blue. All values range from 0 (least intense) to 65535 (highest intensity).
notebook :: EffRef m => [(String, Widget m)] -> Widget mSource
Notebook (tabs).
The tabs are created lazily.
cell_ :: (EffRef m, Eq a) => ReadRef m a -> (forall x. (Widget m -> m x) -> a -> m (m x)) -> Widget mSource
Dynamic cell.
The monadic action for inner widget creation is memoised in the first monad layer.
action :: EffRef m => m (Widget m) -> Widget mSource
action
makes possible to do any EffRef
action while creating the widget.
Derived constructs
cell :: (EffRef m, Eq a) => ReadRef m a -> (a -> Widget m) -> Widget mSource
Dynamic cell.
The inner widgets are memoised.
cellNoMemo :: (EffRef m, Eq a) => ReadRef m a -> (a -> Widget m) -> Widget mSource
Dynamic cell.
The inner widgets are not memoised.