Use Javascript Libraries

Afp

Task description

Recently a Javascript backend was added to Utrecht Haskell Compiler (UHC). This allows the use of existing Javascript libraries from within Haskell. As there are various of such libraries around, as well as various ways of modeling these in Haskell, this project actually consists of multiple projects. Approaches to modeling can be inspired by existing libraries such as wxHaskell or paradigms such as FRP (Functional Reactive Programming). The most prominent issue to be dealt with is how to use types in Haskell to wrap around almost untyped OO functionality. The choice of a specific Javascript library is free, apart from the preference for widely used 'standard' libraries.

Slides

Link

Source

Source code can be found on github: https://github.com/serras/reactive-js Soon to be also avaliable in the UHC examples repository.

Interesting links

Comparison between UI libraries in Haskell

The different frameworks for UI differ in:
  • How they get extensible sets of properties
  • How events and dataflow are handled
  • How they get layout done

Phooey

  • No extensible properties. If needed, uses whHaskell approach.
  • Widgets get a fixed number of parameters and may "return" some value using a monadic interface. When one of these values change, the UI is updated.
  • Example:
    do
      a <- title "apples" $ isSlider (0, 10) 3
      b <- title "bananas" $ isSlider (0, 10) 7
      title "total" $ showDisplay (lifA2 (+) a b)
    • isSlider is a slider widget, that takes a range and initial value parameter
    • title is a layout widget, that gets the output of the inner widget
  • Uses accumR to define computations that refer to all the previous sequence of values.

Grapefruit

  • For records, has a [[http://www.informatik.tu-cottbus.de/~jeltsch/research/ifl-2009-slides.pdf][special syntax]:
    • Types are encoded with X, :& and `Of`
      X :& Position ::: CSignal `Of` Point
        :& IsActive ::: CSignal `Of` Bool
    • Field names are represented with normal data constructors
      data Position = Position
    • The actual inhabitants of these types are encoded similarly, but using :=
      X :& Caption := pure "Ok"
        :& IsEnabled := fmap isValid input
    • You can add information for input record by decorating the field names with Req or Opt.
  • In general, elements are defined using an arrow where input records are fed and output records are recorded:
    X :& Push := ok <- button -< X :& Caption := pure "Ok"
  • Then a complete UI is a circuit, where inputs and outputs are linked by the arrows:
    mainCircuit = proc () -> do
       rec let title = pure "simple"
               text = SSignal.scan "*" (const . ('*':)) push
       X :& Closure := closure `With` X :& Push := push
          <- window `with` just pushButton
          -< X :& Title := title `With` X :& Text := text
       returnA <- closure
    • `With` and `with` are used to do layout

wxHaskell

  • Uses attributes and properties to define extensible records. Different classes of widgets have different sets of attributes.
  • Example of use, update and retrieval of properties:
    do f <- frame [text := "Hello"]
       set f [layout := widget quit]
       t <- get f text
  • Events are defined with on properties:
    do b <- button [on (charKey 'p') := set t [enabled :~ not]]
    • We can see that events can be parametrized,
    • :~ updates the value with a function instead of replacing it.

Fruit

  • Information about widgets is maintained in special datatypes WidgetConf, which contain all input.
    • Those types are actually State -> State, so you can use update functions generated by Haskell's labeled field syntax
    • For example, in ButtonConf, we have the properties:
      btext :: String -> ButtonConf
      enabled :: Bool -> ButtonConf
      so we can establish properties with
      (btext "Hi" . enabled False)
  • As in Grapefruit, GUIs are described using arrow syntax.
    • Indeed, the entire GUI is seen as SignalTransformer (GUIInput, a) (Picture, b)
  • In the paper, a cure is shown for interfaces that change dinamically, using switch, that changes one GUI to another.
    • As it is often used along with an accumulator, a function accumST is provided.
  • Layout is achieved by several combinators, such as besideGUI:
    hello = proc (inpS, _) -> do
       (fbutton `besideGUI` flabel) -< (inpS, ltext "Hi")

-- AlejandroSerrano - 30 Nov 2010