1 / 46

wxHaskell

wxHaskell. Daan Leijen. Ok…. Dat lijkt me een goed plan. Denk je dat je zo iets dinsdag af kunt

zandra
Download Presentation

wxHaskell

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. wxHaskell Daan Leijen

  2. Ok…. Dat lijkt me een goed plan. Denk je dat je zo iets dinsdag af kunt hebben en presenteren?DoaitseOn donderdag, september 18, 2003, at 10:43 AM, Daan Leijen wrote:Nog even over AFP. De turtle-graphics opdracht is volgensmij goed te doen met wxHaskell -- behalve dan dat hetgeinstalleerd dient te worden.Als je wilt kunnen we misschien wat details afspreken endat ik dan wat help om de opdracht vorm te geven met1) een werkend voorbeeld, en 2) concrete vragen.

  3. Overview • wxHaskell as a concrete example of FFI, phantom types, existential types, combinator design, inheritance simulation, and IO as first-class values. • Homework: implement a "turtle" graphics combinator library.

  4. wxHaskell • wxHaskell is a portable GUI library for Haskell build upon the wxWindows (C++) library. • Two layers: a "core" binding (WXCore) and a haskellized layer (WX).

  5. Hello world hello :: IO () hello = do f    <- frame    [text := "Hello!"] quit <- button f [text := "Quit" ,on command := close f] set f [layout := widget quit]

  6. Layout combinators set f [layout := margin 10 (column 5 [floatCentre (label "Hello") ,floatCentre (widget quit) ] ) ]

  7. Demo

  8. What is needed? • Foreign Function Interface (FFI) • Model inheritance • Create abstractions: • Layout combinators • Properties (get/set)

  9. FFI • What are the primitives that you need to interface to the imperative world from Haskell?

  10. 4 primitive operations are needed. • Call the outside world (foreign import) • Be called (foreign export) • Use foreign data (CInt, Addr) • Export haskell data (StablePtr a)

  11. Examples: foreign import sin :: Double -> IO Double foreign import strlen :: Addr -> IO CInt

  12. Phantom types • Make "Addr" typesafe: type Ptr a = Addr foreign import strlen :: Ptr Char -> IO Int

  13. Abstraction foreign import strlen :: Ptr Char -> IO Int strLen :: String -> Int strLen s = unsafePerformIO $ withCString s $ \cstr -> strlen cstr

  14. Abstraction withCString :: String -> (Ptr Char -> IO a) -> IO a withCString s f = do p <- malloc (length s+1) mapM_ (poke p) (zip s [0..]) x <- f p free p return x

  15. wxHaskell windowSetLabel :: Window a -> String -> IO () windowSetLabel w txt = withCString txt $ \cstr -> primWindowSetLabel w txt foreign import "windowSetLabel" primWindowSetLabel :: Window a -> Ptr Char -> IO ()

  16. Inheritance • How to model inheritance? class Window { void setLabel( const char* txt ); .. }; class Frame : public Window { void maximize( void ); .. };

  17. Simple model. type Window = Ptr CWindowdata CWindow = CWindowtype Frame = Ptr CFrame data CFrame = CFrame windowCreate :: IO WindowwindowSetLabel :: Window -> String -> IO () frameCreate :: IO Frame frameMaximize :: Frame -> IO ()

  18. Conversions? windowFromFrame :: Frame -> Window  do f <- frameCreate windowSetLabel (windowFromFrame f)

  19. Encode inheritance in phantom type type Window a = Ptr (CWindow a) data CWindow a = CWindow type Frame a = Window (CFrame a) data CFrame a = CFrame windowCreate :: IO (Window ()) windowSetLabel :: Window a -> String -> IO () frameCreate :: IO (Frame ()) frameMaximize :: Frame a -> IO ()

  20. It works now do f <- frameCreate windowSetLabel f "Hi" f :: Frame () == Window (CFrame ()) == Ptr (CWindow (CFrame ())) windowSetLabel :: Window a -> String -> IO ()

  21. Properties • How can we model the "property" methods? windowGetLabel :: Window a -> IO String windowSetLabel :: Window a -> String -> IO () windowGetLayout :: Window a -> IO Layout windowSetLayout :: Window a -> Layout -> IO () ..

  22. Get/Set • We would like to have generic "get" and "set" functions: get :: w -> Attr -> IO a set :: w -> Attr -> a -> IO ()

  23. Typed get/set get :: w -> Attr w a -> IO a set :: w -> Attr w a -> a -> IO () text :: Attr (Window a) String

  24. Attributes data Attr w a = Attr (w -> IO a) (w -> a -> IO ()) text :: Attr (Window a) String text = Attr windowGetLabel windowSetLabel

  25. Generic get/set get :: w -> Attr w a -> IO a get w (Attr getter setter) = getter w set :: w -> Attr w a -> a -> IO () set w (Attr getter setter) x = setter w x

  26. Problems • I would like to set many "properties" at once: set frame text "hi" set frame size (sz 300 300) set frame color blue == (?) map (set frame) [text "hi", size (sz 300 300), color blue]

  27. Properties • Properties save a value/attribute pair. data Prop w = Prop (w -> IO ()) prop :: Attr w a -> a -> Prop w prop (Attr getter setter) x = Prop (\w -> setter w x) set :: w -> [Prop w] -> IO () set w props = mapM_ setprop props where setprop (Prop setter) = setter w

  28. Now we can set many properties set frame [prop text "hi" ,prop color blue ,prop size (sz 300 300) ]

  29. Problem • I want a nicer notation: prop text "hi"  text := "hi"

  30. Existentials data Prop w = (:=) (Attr w a) a  data Prop w = forall a. (:=) (Attr w a) a

  31. New definition of "set" set :: w -> [Prop w] -> IO () set w props = mapM_ setprop props where setprop ((Attr getter setter) := x) = setter w x

  32. Definition of "frame" frame :: [Prop (Frame ())] -> IO (Frame ()) frame props = do f <- frameCreate idAny "" rectNull 0 set f props return f

  33. A combinator language for layout set f [layout := margin 10 (column 5 [floatCentre (label "Hello") ,floatCentre (widget quit) ] ) ]

  34. Example: C++ vs. Combinators f <- frame [text "Demo"] ok <- button f [text "Ok"] can <- button f [text "Cancel"] txt <- textCtrl f AlignLeft [clientSize := sz 100 60] set f [layout := margin 10 $ column 10 [ fill $ widget txt , hfill $ row 10 [widget ok, widget can] ] ]

  35. Abstract data type data Layout windowSetLayout :: Window a -> Layout -> IO () do f <- frameCreate idAny "Test" rectNull 0 ok <- buttonCreate f idAny "Bye" rectNull 0 windowSetLayout f (widget ok)

  36. Primitives widget :: Window a -> Layout label :: String -> Layout space :: Size -> Layout

  37. Containers grid :: Int -> Int -> [[Layout]] -> Layout grid 5 5 [[label "x", widget xinput] ,[label "y", widget yinput]]

  38. Containers 2 row :: Int -> [Layout] -> Layout column :: Int -> [Layout] -> Layout row n xs = grid n 0 [xs] column n xs = grid 0 n (map (\x -> [x]) xs) column 5 [grid 5 5 [[label "x", widget xinput] ,[label "y", widget yinput]] row 5 [widget ok, widget cancel]]

  39. Attributes margin :: Int -> Layout -> Layout align :: Align -> Layout -> Layout shaped :: Layout -> Layout expand :: Layout -> Layout

  40. Stretch hstretch, vstretch, stretch :: Layout -> Layout stretch = hstretch . vstretch column 5 $[grid 5 5 [[label "x", hstretch $ expand $ widget xinput] ,[label "y", hstretch $ expand $ widget yinput]],stretch $ alignBottomRight $ row 5 [widget ok, widget cancel]]

  41. Many helpers fill = stretch . expand hfill = hstretch . expand floatBottomRight = stretch . alignBottomRight empty = space (sz 0 0) glue = fill empty hglue = hfill empty

  42. Implementation data Layout = Widget (Window ()) | Label String | Grid Int Int [[Layout]]

  43. Transformers data Layout = Widget { options :: Options, ..} | Label { options :: Options, ..} | Grid { options :: Options, ..} data Options = Options{ stretchH :: Bool , stretchV :: Bool , marginW :: Int , .. }

  44. Generate Layout widget w = Widget defaultOptions w label s = Label defaultOptions s hstretch layout = updateOptions (\opt -> opt { stretchH = True }) layout updateOptions f layout = layout{ options = f (options layout) }

  45. Translate Layout windowSetLayout :: Window a -> Layout -> IO () windowSetLayout w (Label options s) = do lab <- staticTextCreate s sizer <- windowSizerCreate lab (flags options) windowAddSizer w sizer.. flags options = (if stretchH options then wxHSTRETCH else 0) + (if stretchV options then wxVSTRETCH else 0) + ..

  46. Assignment: Turtle graphics • Design and implement an embedding of the LOGO language in Haskell. • Motivate your design decisions! • Deadline: this Sunday. • http://wxhaskell.sourceforge.net/assignment.html • daan@cs.uu.nl

More Related