Difference between revisions of "LGtk"
Jump to navigation
Jump to search
m (→Lenses) |
(→External links: remove dead link) |
||
(24 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
[[Category:User interfaces]] |
[[Category:User interfaces]] |
||
− | == What is it? == |
||
− | LGtk is a |
+ | LGtk is a GUI Toolkit. |
− | LGtk is built on Gtk2Hs. |
||
+ | Main goals of LGtk: |
||
− | Most Haskellers would like to use a mature FRP-based API for creating graphical user interfaces. |
||
− | FRP may not be the best tool for special user interfaces, like interfaces which consists of buttons, checkboxes, combo boxes, text entries and menus only. |
||
− | LGtk has a lens-based API which fits better these user interfaces. |
||
+ | * Provide a Haskell EDSL for declarative description of interactive graphical applications |
||
− | == Semantics overview == |
||
+ | * Provide an API for custom widget design |
||
− | |||
+ | * Provide a playground for high-level declarative features like derived state-save and undo-redo operations and type-driven GUI generation |
||
− | The semantics of LGtk is given by a reference implementation. |
||
− | The reference implementation is given in the following stages. |
||
− | |||
− | === Lenses === |
||
− | |||
− | LGtk use simple lenses, defined in the data-lens package: |
||
− | |||
− | <haskell> |
||
− | newtype Lens a b = Lens { runLens :: a -> Store b a } |
||
− | </haskell> |
||
− | |||
− | This data type is isomorphic to <hask>(a -> b, b -> a -> a)</hask>, the well-know lens data type. |
||
− | |||
− | In certain places LGtk allows to use non-pure lenses, i.e. lenses which |
||
− | brake lens laws. Those places are explicitly marked and explained in this overview. |
||
− | |||
− | === References === |
||
− | |||
− | It is convenient to use lenses with the state monad |
||
− | ([http://www.haskellforall.com/2013/05/program-imperatively-using-haskell.html see this use case]) and the reader monad. |
||
− | |||
− | Let's call <hask>Lens s a</hask> a '''reference''' of the state monad <hask>State s</hask> and the reader monad <hask>Reader s</hask>. |
||
− | |||
− | References are distinguished from lenses, because we would like to make the program state <hask>s</hask> unaccessible to guarantee linear use of the state for example. |
||
− | |||
− | There are several ways to model references in Haskell. |
||
− | LGtk models them with type classes and associated types, but that is a technical detail here. |
||
− | |||
− | ==== Types ==== |
||
− | |||
− | Instead of giving a concrete implementation in Haskell, suppose that |
||
− | |||
− | * <hask>s</hask> is a fixed type, |
||
− | * <hask>Ref</hask>, the type of references is isomorphic to <hask>Lens s</hask>, |
||
− | * <hask>S</hask> is isomorphic to <hask>State s</hask>, |
||
− | * <hask>R</hask> is isomorphic to <hask>Reader s</hask>. |
||
− | |||
− | The isomorphisms are not exposed in the API. |
||
− | |||
− | ==== Operations ==== |
||
− | |||
− | Exposed operations of <hask>Ref</hask>, <hask>S</hask> and <hask>R</hask>: |
||
− | |||
− | * The <hask>Monad</hask> instance of <hask>S</hask> and <hask>R</hask> |
||
− | |||
− | * The monad morphism between <hask>R</hask> and <hask>S</hask> |
||
− | |||
− | <haskell> |
||
− | liftReadPart :: R a -> S a |
||
− | liftReadPart = gets . runReader |
||
− | </haskell> |
||
− | |||
− | * Reference read |
||
− | |||
− | <haskell> |
||
− | readRef :: Ref a -> R a |
||
− | readRef = reader . getL |
||
− | </haskell> |
||
− | |||
− | * Reference write |
||
− | |||
− | <haskell> |
||
− | writeRef :: Ref a -> a -> S () |
||
− | writeRef = modify . setL r |
||
− | </haskell> |
||
− | |||
− | * Lens application on a reference |
||
− | |||
− | <haskell> |
||
− | lensMap :: Lens a b -> Ref a -> Ref b |
||
− | lensMap = (.) |
||
− | </haskell> |
||
− | |||
− | * Joining of references |
||
− | |||
− | <haskell> |
||
− | joinRef :: R (Ref a) -> Ref a |
||
− | joinRef = Lens . join . (runLens .) . runReader |
||
− | </haskell> |
||
− | |||
− | * The unit reference |
||
− | |||
− | <haskell> |
||
− | unitRef :: r () |
||
− | unitRef = lens (const ()) (const id) |
||
− | </haskell> |
||
− | |||
− | Note that the identity lens is '''not''' a reference because that would leak the program state <hask>s</hask>. |
||
− | |||
− | ==== Reference creation ==== |
||
− | |||
− | TODO |
||
− | |||
− | === Lens-trees === |
||
− | |||
− | TODO |
||
− | |||
− | === Effects === |
||
− | |||
− | TODO |
||
− | |||
− | == Examples == |
||
− | |||
− | === Hello World === |
||
− | |||
− | <haskell> |
||
− | main = runWidget $ label $ return "Hello World!" |
||
− | </haskell> |
||
− | |||
− | <hask>return</hask> is neded because labels may be dynamic, see the next examples. |
||
− | |||
− | === Copy === |
||
− | |||
− | The following applications presents an entry and a label below of it. |
||
− | When a text is entered in the entry, the label is changed to the entered text. |
||
− | |||
− | <haskell> |
||
− | main = runWidget $ action $ do |
||
− | r <- newRef "enter text here" |
||
− | return $ vcat |
||
− | [ entry r |
||
− | , label $ readRef r |
||
− | ] |
||
− | </haskell> |
||
− | |||
− | <hask>action</hask> gives acces to a monad in which new references can be made by <hask>newRef</hask>. |
||
− | A crutial feature of LGtk is that you cannot change the value of references in this monad (you can read them though). |
||
− | |||
− | <hask>label</hask> gives acces to a monad in which you can read references but no reference creation or write is possible. |
||
− | |||
− | === Addition === |
||
− | |||
− | Two entries of integers and a label which shows the sum: |
||
− | |||
− | <haskell> |
||
− | main = runWidget $ action $ do |
||
− | r1 <- newRef (12 :: Integer) |
||
− | r2 <- newRef 4 |
||
− | return $ vcat |
||
− | [ entryShow r1 |
||
− | , entryShow r2 |
||
− | , label $ liftM show $ liftM2 (+) (readRef r1) (readRef r2) |
||
− | ] |
||
− | </haskell> |
||
− | |||
− | === Complex examples === |
||
− | |||
− | You can find more complex examples in the source code of LGtk. |
||
− | More examples will be presented here also. |
||
[[Image:Lgtkdemo.png]] |
[[Image:Lgtkdemo.png]] |
||
− | == |
+ | == Internal links == |
− | |||
− | Features of lgtk-0.5 |
||
− | |||
− | * The API is closed, you can safely use any constructs as far as you obey the documented laws. |
||
− | * Support for asynchronous events. Using LGtk is a safe way for writing multithreaded Gtk applications. |
||
− | * The semantics is getting stable but it is not yet documented. |
||
− | |||
− | TODO list: |
||
− | |||
− | * Add an efficient implementation for LGtk. LGtk has only a reference implementation currently. |
||
− | * Add support for styles (layout, colors, etc). |
||
− | * Support more Gtk constructs. |
||
− | |||
− | |||
− | == Demo application == |
||
− | |||
− | You can try the demo application with the following commands: |
||
− | |||
− | cabal install gtk2hs-buildtools |
||
− | cabal install lgtk |
||
− | lgtkdemo |
||
− | |||
− | == Changelog == |
||
− | |||
− | === lgtk-0.5.1 === |
||
− | |||
− | * Documentation fixes and cleanup |
||
− | * Try to support Haskell Platform 2012.4.0.0 |
||
+ | Should be revised: |
||
− | === lgtk-0.5 === |
||
+ | * [[LGtk/Semantics]] |
||
− | * Do not use monadic lenses any more. |
||
+ | * [[LGtk/ADT_lenses]] |
||
− | * Support for asynchronous events. |
||
− | * Lazily created tabs. |
||
− | * Unactive tabs are really unactive (event handlers are detached). |
||
− | * File references watch the files. When the file changes, the GUI is updated. |
||
− | * References with inherent identity (makes defining auto-sensitive buttons easier) |
||
− | * Experimental support for colored buttons. |
||
− | * More examples in the demo application. |
||
− | * Lots of inner changes. |
||
== External links == |
== External links == |
||
− | * [http://hackage.haskell.org/package/lgtk |
+ | * [http://hackage.haskell.org/package/lgtk Haddock documentation on HackageDB] |
− | * [ |
+ | * [https://github.com/divipp/lgtk GitHub repository] |
* [http://people.inf.elte.hu/divip/LGtk/LGtk.html Initial announcement] |
* [http://people.inf.elte.hu/divip/LGtk/LGtk.html Initial announcement] |
||
+ | * [http://www.haskell.org/haskellwiki/LGtk haskell.org wiki page (this page)] |
||
Related Stackoverflow questions: |
Related Stackoverflow questions: |
||
Line 218: | Line 32: | ||
Reddit comments: |
Reddit comments: |
||
− | * [http://www.reddit.com/r/haskell/comments/1cemr2/lgtk_lensbased_gtk_interface/ 15 April] |
+ | * [http://www.reddit.com/r/haskell/comments/1cemr2/lgtk_lensbased_gtk_interface/ 15 April 2013] |
− | * [http://www.reddit.com/r/haskell/comments/1cj0o6/lgtk_api_fixed/ 17 April] |
+ | * [http://www.reddit.com/r/haskell/comments/1cj0o6/lgtk_api_fixed/ 17 April 2013] |
− | * [http://www.reddit.com/r/haskell/comments/1f5m5j/ann_lgtk_05/ 27 May] |
+ | * [http://www.reddit.com/r/haskell/comments/1f5m5j/ann_lgtk_05/ 27 May 2013] |
+ | * [http://www.reddit.com/r/haskell/comments/1fjerf/lens_chains_lgtk_semantics_first_part/ 2 June 2013] |
||
+ | * [http://www.reddit.com/r/haskell/comments/25k9x1/ann_lgtk08/ 14 May 2014] |
Latest revision as of 21:08, 22 July 2023
LGtk is a GUI Toolkit.
Main goals of LGtk:
- Provide a Haskell EDSL for declarative description of interactive graphical applications
- Provide an API for custom widget design
- Provide a playground for high-level declarative features like derived state-save and undo-redo operations and type-driven GUI generation
Internal links
Should be revised:
External links
- Haddock documentation on HackageDB
- GitHub repository
- Initial announcement
- haskell.org wiki page (this page)
Related Stackoverflow questions:
Reddit comments: