MaintainerThomas Hallgren
Safe HaskellNone




Web Fudgets is a prototype library for writing web application in a functional style in Haskell.

Web Fudgets is based on Fudgets (a Graphical User Interface Libary for Haskell developed in the early 1990s) but has a completely separate implementation on top of Haste.


The Fudget type

data F hi ho #

F hi ho is the type of a fudget that consumes an high-level input stream of values of type hi and produces an high-level output stream of values of type ho. It can also generate a number of user interface elements, and can read input from and send output to those user interface elements.


Functor (F hi) # 


fmap :: (a -> b) -> F hi a -> F hi b

(<$) :: a -> F hi b -> F hi a

Monoid (F hi ho) # 


mempty :: F hi ho

mappend :: F hi ho -> F hi ho -> F hi ho

mconcat :: [F hi ho] -> F hi ho

Running a fudget

runF :: F t t1 -> IO () #

runF is typically used only once in the main function of a program. It runs the fudget and adds any user interface elements it generates to the documentBody of the web page.

User interface elements

buttonF :: String -> F ButtonClick ButtonClick #

Creates a button, like <input type="button" value="label">. It outputs BtnClick when pressed. (BtnClick received on the input is propagated directly to the output, allowing button clicks to be simulated programmatically.)

data ButtonClick #




Eq ButtonClick # 


(==) :: ButtonClick -> ButtonClick -> Bool

(/=) :: ButtonClick -> ButtonClick -> Bool

Read ButtonClick # 


readsPrec :: Int -> ReadS ButtonClick

readList :: ReadS [ButtonClick]

readPrec :: ReadPrec ButtonClick

readListPrec :: ReadPrec [ButtonClick]

Show ButtonClick # 


showsPrec :: Int -> ButtonClick -> ShowS

show :: ButtonClick -> String

showList :: [ButtonClick] -> ShowS

buttonGroupF :: F t b -> F (Either ButtonClick t) (Either ButtonClick b) #

Creates a button with another fudget inside (which should be something simple, e.g. an imgF or a stringDisplayF...), <button>...</button>.

toggleButtonF :: String -> F Bool Bool #

A checkboxF with a label

checkboxF :: F Bool Bool #

A checkbox, <input type=checkbox>. (Slightly buggy at the moment: sending in False does not unckeck the checkbox.)

selectF :: Eq alt => [(alt, String)] -> alt -> F alt alt #

A menu of options, <select><option>...</option>...</select>

stringDisplayF :: F String ho #

An output-only element displaying text, <span>...</span>

showF :: Show i => F i o #

stringDisplayF combined with show

readShowF :: (Show a, Read a) => F a a #

stringF combined with show and read

numberF :: (Show a, Read a, Num a) => F a a #

readShowF restricted to numbers, <input type="number">

stringF :: F String String #

A string input/output field, <input type="text">

passwordF :: F String String #

A string input/output field that shows **** instead of the actual input, <input type="password">

canvasF :: (Int, Int) -> F (Picture ()) (MouseEvent, MouseData) #

Creates a canvas of given width and height. Use the Picture type from Haste.Graphics.Canvas to draw things. The canvas outputs MouseUp events (becase MouseUp seems to work for both the left and the right mouse button, while Click only works for the left mouse button).

imgF :: URL -> F URL o #

An image, <img src="url" alt=""> You can change the image dynamically by sending in the URL of another image.

imgF' :: [Attribute] -> URL -> F URL o #

An image with extra attributes, <img src="url" ...>. You can change the image dynamically by sending in the URL of another image.

Static content

textF :: String -> F hi ho #

Plain text

htmlF :: String -> F hi ho #

Text with HTML markup

ahrefF :: URL -> F i o -> F i o #

A hyperlink <a href="url">...</a>


h1F :: F hi ho -> F hi ho #

Level 1 header <h1>...</h1>

h2F :: F hi ho -> F hi ho #

Level 2 header <h2>...</h2>

h3F :: F hi ho -> F hi ho #

Level 3 header <h3>...</h3>

pF :: F hi ho -> F hi ho #

Paragraph <p>...</p>

tableF :: Int -> F hi ho -> F hi ho #

A table with n columns

divF :: F hi ho -> F hi ho #

A div element <div>...</div>

boxF :: F hi ho -> F hi ho #

A div element with a black border and some padding

ulF :: F hi ho -> F hi ho #

Unordered list <ul>...</ul>

liF :: F hi ho -> F hi ho #

List item <li>...</li>

preF :: F hi ho -> F hi ho #

A pre element <pre>...</pre>

withF :: F hi ho -> [Attribute] -> F hi ho #

Apply attributes to the elements generated by a fudget

Fudget combinators

Parallel composition

(>+<) :: F t a -> F t1 b -> F (Either t t1) (Either a b) infixl 5 #

Tagged parallel composition. Messages to/from the left fudget are tagged Left. Messages to/from the right fudget are tagged Right.

(>+) :: F hi ho -> F t t1 -> F hi ho infixl 5 #

Parallel composition where only the left fudget is connected. The right fudget is typically static content.

(+<) :: F t t1 -> F hi ho -> F hi ho infixl 5 #

Parallel composition where only the right fudget is connected. The left fudget is typically static content.

listF :: Eq a => [(a, F t b)] -> F (a, t) (a, b) #

Tagged parallel composition of a list of fudgets

Serial composition

(=<=) :: F t ho -> F hi t -> F hi ho infixr 3 #

Right-to-left serial composition. The output stream of the right fudget is connected to the input stream of the left fudget. This was originally called >==< in Fudgets.

(=>=) :: F hi t -> F t ho -> F hi ho infixr 3 #

Left-to-right serial composition. The output stream of the left fudget is connected to the input stream of the right fudget. (This was not included in the original implementation of Fudgets. Using both =>= and =<= in the same expression might lead to confusion...)


loopLeftF :: F (Either a hi) (Either a ho) -> F hi ho #

Creates a feedback loop. loopLeftF fud behaves as follows: output from fud tagged Left will be sent back to the input of fud. Output from fud tagged Right will be sent to the output of loopLeftF fud. Input to loopLeftF fud will be tagged Right and delivered to fud.

loopThroughRightF :: F (Either a b) (Either c d) -> F c a -> F b d #

loopThroughRightF master slave is similar to loopLeftF master, but the loop goes through the slave fudget. (A better name might be encapsulateF since all communication with the slave has to go via the master, so the slave is encapsulated in this sense.)

Adding application specific functionality


mapF :: (a -> ho) -> F a ho #

Like map for lists. mapF f outputs f x for every x in the input stream

filterF :: (ho -> Bool) -> F ho ho #

Like filter for lists. Propagates values from the input stream to the output stream if they pass a test.

mapMaybeF :: (a -> Maybe ho) -> F a ho #

Like mapMaybe for lists. A combination of mapF and filterF.

concatMapF :: (i -> [o]) -> F i o #

Like concatMap for lists. A combination of concatF and mapF.


stateF :: (a -> hi -> (a, ho)) -> a -> F hi ho #

stateF is used to maintain an internal state. Given a state transition function f and an initial state s, stateF f s responds to input by applying f to it to update the internal state and generate an output.

Stream processors

idF :: F ho ho #

mapF id, propagates all input directly to the output

putF :: ho -> F hi ho -> F hi ho #

putF x fud outputs x, then behaves like fud

nullF :: F t ho #

Ignores all input. Doesn't produce any output.

concatF :: F [i] i #

Like concat for lists, flattens a stream of lists.


timerF :: F (Maybe Interval) Tick #

timerF outputs Tick after a specified delay or at regular intervals. The timer starts when it receives Just interval on its input. The timer stops when it receives Nothing in its input.

data Tick #




Eq Tick # 


(==) :: Tick -> Tick -> Bool

(/=) :: Tick -> Tick -> Bool

Show Tick # 


showsPrec :: Int -> Tick -> ShowS

show :: Tick -> String

showList :: [Tick] -> ShowS

Haste extras

addStyleLink :: MonadIO m => URL -> m () #

Add a link to a style sheet to the document head, <link rel="stylesheet" type="text/css" href="url">

documentHead :: Elem #

Re-exported from Haste

type URL = String #

data Attribute :: * #

(=:) :: AttrName -> AttrValue -> Attribute #

attr :: String -> AttrName #

style :: String -> AttrName #

prop :: String -> AttrName #

type AttrValue = String #

data MouseEvent :: * #


Event MouseEvent 

Associated Types

type EventData MouseEvent :: *


eventName :: MouseEvent -> JSString

eventData :: MouseEvent -> JSAny -> IO (EventData MouseEvent)

type EventData MouseEvent 
type EventData MouseEvent = MouseData

data MouseData :: * #




data Interval :: * #


Once ~Int 
Repeat ~Int 

Orphan instances

Show Interval # 


showsPrec :: Int -> Interval -> ShowS

show :: Interval -> String

showList :: [Interval] -> ShowS