-
Notifications
You must be signed in to change notification settings - Fork 20
Expand file tree
/
Copy pathMenu.hs
More file actions
51 lines (47 loc) · 1.66 KB
/
Menu.hs
File metadata and controls
51 lines (47 loc) · 1.66 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
{-# LANGUAGE OverloadedStrings #-}
module Main where
import Control.Monad (forever)
import Concur.Core
import Concur.React
-- Demonstration of how easy it is to build a simple generic menu widget
-- 1. This uses no state, as it was easy to build this using monadic flow
-- 2. It was built by composing sub-widgets in a style that feels very functional.
-- Top, open, menuItem, and menuButton are legitimate widgets on their own.
menu :: [(String, [(a,String)])] -> Widget HTML a
menu cs = top 0 items >>= open items
where
items = menuItem <$> cs
top i opts = orr $ zipWith (\(a,b) j -> a >>= \v -> return (b v,j)) opts [i..]
open opts (b,i) =
let w = [Left <$> top 0 (take i opts), Right <$> b, Left <$> top (i+1) (drop (i+1) opts)]
in orr w >>= either (open opts) return
menuItem (label, children) =
( el_ "div" [vattr "className" "menu"] $ button' [] (text label)
, const $ el_ "div" [vattr "className" "menu"] $ orr $ map menuButton children
)
menuButton (ret,str) = ret <$ button' [] (text str)
main :: IO ()
main = runWidgetInBody $ forever $ do
v <- menu items
el "div" [] $ [text $ "You picked - " ++ v, button' [] $ text "Restart"]
where
items =
[ ("Fruits",
[ ("Apple","Apple")
, ("Banana","Banana")
]
)
, ("Veggies",
[ ("Tomato","Tomato")
, ("Potato","Potato")
]
)
, ("Colors",
[ ("Red","Red")
, ("Green","Green")
, ("Blue","Blue")
, ("White","White")
, ("Orange","Orange")
]
)
]