on master help sign in
Merge branch 'dev' into release-candidate
commitcd8ade670aac49eebfe907046cead7e88e8e7548 authorEvan Czaplicki <info@elm-lang.org> dateTue 3 Sep 2013, 01:30 (13 years ago) parent136fbe5bdd8213
3 files changed+221−144
compiler/Generate/JavaScript.hs+3−3 libraries/Graphics/Input.elm+115−76 libraries/List.elm+103−65
compiler/Generate/JavaScript.hs+3−3
@@ -378,10 +378,10 @@ binop span op e1 e2 =
378378
379379 opDict = Map.fromList (infixOps ++ specialOps)
380380
381− specialOp str func = ("Basics." ++ str, func)
381+ specialOp str func = [ (str, func), ("Basics." ++ str, func) ]
382382 infixOp str op = specialOp str (InfixExpr () op)
383383
384− infixOps =
384+ infixOps = concat
385385 [ infixOp "+" OpAdd
386386 , infixOp "-" OpSub
387387 , infixOp "*" OpMul
@@ -390,7 +390,7 @@ binop span op e1 e2 =
390390 , infixOp "||" OpLOr
391391 ]
392392
393− specialOps =
393+ specialOps = concat
394394 [ specialOp "^" $ \a b -> obj "Math.pow" `call` [a,b]
395395 , specialOp "|>" $ flip (<|)
396396 , specialOp "==" $ \a b -> obj "_N.eq" `call` [a,b]
libraries/Graphics/Input.elm+115−76
@@ -1,6 +1,31 @@
1−
21module Graphics.Input where
32
3+{-| This module is for creating standard input widgets such as buttons and
4+text boxes. In general, functions in this library return a signal representing
5+events from the user.
6+
7+The simplest inputs are *one-way inputs*, meaning the user can update
8+them, but the programmer cannot. If you need to update an input from
9+within the program you want the slightly more complex *two-way inputs*.
10+This document will always show the one-way inputs first, *then* the
11+two-way inputs.
12+
13+# Buttons
14+@docs button, customButton, buttons, customButtons
15+
16+# Fields
17+@docs field, password, email, fields, FieldState, emptyFieldState
18+
19+# Checkboxes
20+@docs checkbox, checkboxes
21+
22+# Drop Downs
23+@docs stringDropDown, dropDown
24+
25+# Mouse Hover
26+@docs hoverable, hoverables
27+-}
28+
429import Basics (String)
530import Signal (Signal,lift,dropRepeats)
631import Native.Graphics.Input
@@ -11,116 +36,127 @@ import JavaScript (JSString)
1136
1237id x = x
1338
14−-- Create a group of buttons.
15−--
16−-- * The first argument is the default value of the `events` signal.
17−-- * The `events` signal represents all of the activity in this group
18−-- of buttons.
19−-- * The `button` function creates a button
20−-- with the given name, like &ldquo;Submit&rdquo; or &ldquo;Cancel&rdquo;.
21−-- The `a` value is sent to `events` whenever the button is pressed.
39+{-| Create a group of buttons.
40+
41+ * The first argument is the default value of the `events` signal.
42+ * The `events` signal represents all of the activity in this group
43+ of buttons.
44+ * The `button` function creates a button
45+ with the given name, like &ldquo;Submit&rdquo; or &ldquo;Cancel&rdquo;.
46+ The `a` value is sent to `events` whenever the button is pressed.
47+-}
2248buttons : a -> { events : Signal a,
2349 button : a -> String -> Element }
2450buttons = Native.Graphics.Input.buttons
2551
26−-- Create a button with a given label. The result is an `Element` and
27−-- a signal of units. This signal triggers whenever the button is pressed.
52+{-| Create a button with a given label. The result is an `Element` and
53+a signal of units. This signal triggers whenever the button is pressed.
54+-}
2855button : String -> (Element, Signal ())
2956button txt =
3057 let pool = buttons ()
3158 in (pool.button () txt, pool.events)
3259
33−-- Create a group of custom buttons.
34−--
35−-- * The first argument is the default value of the `events` signal.
36−-- * The `events` signal represents all of the activity in this group
37−-- of custom buttons.
38−-- * The `customButton` function creates a button with three different visual
39−-- states, one for up, hovering, and down. The resulting button has dimensions
40−-- large enough to fit all three possible `Elements`.
41−-- The `a` value is sent to `events` whenever the button is pressed.
60+{-| Create a group of custom buttons.
61+
62+ * The first argument is the default value of the `events` signal.
63+ * The `events` signal represents all of the activity in this group
64+ of custom buttons.
65+ * The `customButton` function creates a button with three different visual
66+ states, one for up, hovering, and down. The resulting button has dimensions
67+ large enough to fit all three possible `Elements`.
68+ The `a` value is sent to `events` whenever the button is pressed.
69+-}
4270customButtons : a -> { events : Signal a,
4371 customButton : a -> Element -> Element -> Element -> Element }
4472customButtons = Native.Graphics.Input.customButtons
4573
46−-- Create a button with custom states for up, hovering, and down
47−-- (given in that order). The result is an `Element` and
48−-- a signal of units. This signal triggers whenever the button is pressed.
74+{-| Create a button with custom states for up, hovering, and down
75+(given in that order). The result is an `Element` and a signal of
76+units. This signal triggers whenever the button is pressed.
77+-}
4978customButton : Element -> Element -> Element -> (Element, Signal ())
5079customButton up hover down =
5180 let pool = customButtons ()
5281 in (pool.customButton () up hover down, pool.events)
5382
54−-- Create a group of checkboxes.
55−--
56−-- * The first argument is the default value of the `events` signal.
57−-- * The `events` signal represents all of the activity in this group
58−-- of checkboxes.
59−-- * The `checkbox` function creates a
60−-- checkbox with a given state. The `(Bool -> a)` function is used
61−-- when the checkbox is modified. It takes the new state and turns
62−-- it into a value that can be sent to `events`. For example, this
63−-- lets you add an ID to distinguish between checkboxes.
83+{-| Create a group of checkboxes.
84+
85+ * The first argument is the default value of the `events` signal.
86+ * The `events` signal represents all of the activity in this group
87+ of checkboxes.
88+ * The `checkbox` function creates a
89+ checkbox with a given state. The `(Bool -> a)` function is used
90+ when the checkbox is modified. It takes the new state and turns
91+ it into a value that can be sent to `events`. For example, this
92+ lets you add an ID to distinguish between checkboxes.
93+-}
6494checkboxes : a -> { events : Signal a,
6595 checkbox : (Bool -> a) -> Bool -> Element }
6696checkboxes = Native.Graphics.Input.checkboxes
6797
68−-- Create a checkbox with a given start state. Unlike `button`, this result
69−-- is a *signal* of elements. That is because a checkbox has state that
70−-- updates based on user input.
71−-- The boolean signal represents the current state of the checkbox.
98+{-| Create a checkbox with a given start state. Unlike `button`, this
99+result is a *signal* of elements. That is because a checkbox has state
100+that updates based on user input. The boolean signal represents the
101+current state of the checkbox.
102+-}
72103checkbox : Bool -> (Signal Element, Signal Bool)
73104checkbox b =
74105 let cbs = checkboxes b
75106 in (lift (cbs.checkbox id) cbs.events, cbs.events)
76107
77−-- Detect when the mouse is hovering over some elements. This
78−-- allows you to create and destroy elements dynamically and still
79−-- detect hover information.
108+{-| Detect when the mouse is hovering over some elements. This
109+allows you to create and destroy elements dynamically and still
110+detect hover information.
111+-}
80112hoverables : a -> { events : Signal a,
81113 hoverable : (Bool -> a) -> Element -> Element }
82114hoverables = Native.Graphics.Input.hoverables
83115
84−-- Detect when the mouse is hovering over a specifici `Element`.
116+{-| Detect when the mouse is hovering over a specifici `Element`. -}
85117hoverable : Element -> (Element, Signal Bool)
86118hoverable elem =
87119 let pool = hoverables False
88120 in (pool.hoverable id elem, pool.events)
89121
90−-- Represents the current state of a text field. The `string` represents the
91−-- characters filling the text field. The `selectionStart` and `selectionEnd`
92−-- values represent what the user has selected with their mouse or keyboard.
93−-- For example:
94−--
95−-- { string="She sells sea shells", selectionStart=3, selectionEnd=0 }
96−--
97−-- This means the user highlighted the substring `"She"` backwards.
122+{-| Represents the current state of a text field. The `string` represents the
123+characters filling the text field. The `selectionStart` and `selectionEnd`
124+values represent what the user has selected with their mouse or keyboard.
125+For example:
126+
127+ { string="She sells sea shells", selectionStart=3, selectionEnd=0 }
128+
129+This means the user highlighted the substring `"She"` backwards.
130+-}
98131type FieldState = { string:String, selectionStart:Int, selectionEnd:Int }
99132
100−-- Create a group of text input fields.
101−--
102−-- * The first argument is the default value of the `events` signal.
103−-- * The `events` signal represents all of the activity in this group
104−-- of text fields.
105−-- * The `field` function creates a
106−-- field with the given ghost text and initial field state.
107−-- When the field is modified, the `(FieldState -> a)` function
108−-- takes the new state and turns
109−-- it into a value that can be sent to `events`. For example, this
110−-- lets you add an ID to distinguish between input fields.
133+{-| Create a group of text input fields.
134+
135+ * The first argument is the default value of the `events` signal.
136+ * The `events` signal represents all of the activity in this group
137+ of text fields.
138+ * The `field` function creates a
139+ field with the given ghost text and initial field state.
140+ When the field is modified, the `(FieldState -> a)` function
141+ takes the new state and turns
142+ it into a value that can be sent to `events`. For example, this
143+ lets you add an ID to distinguish between input fields.
144+-}
111145fields : a -> { events : Signal a,
112146 field : (FieldState -> a) -> String -> FieldState -> Element }
113147fields = Native.Graphics.Input.fields
114148
115−-- The empty field state:
116−--
117−-- { string="", selectionStart=0, selectionEnd=0 }
149+{-| The empty field state:
150+
151+ { string="", selectionStart=0, selectionEnd=0 }
152+-}
118153emptyFieldState : FieldState
119154emptyFieldState = { string="", selectionStart=0, selectionEnd=0 }
120155
121−-- Create a field with the given default text. The output is an element that
122−-- updates to match the user input and a signal of strings representing the
123−-- content of the field.
156+{-| Create a field with the given default text. The output is an element
157+that updates to match the user input and a signal of strings representing
158+the content of the field.
159+-}
124160field : String -> (Signal Element, Signal String)
125161field placeHolder =
126162 let tfs = fields emptyFieldState
@@ -128,7 +164,7 @@ field placeHolder =
128164 in (lift (tfs.field id placeHolder) changes,
129165 dropRepeats (lift .string changes))
130166
131−-- Same as `field` but the UI element blocks out each characters.
167+{-| Same as `field` but the UI element blocks out each characters. -}
132168password : String -> (Signal Element, Signal String)
133169password placeHolder =
134170 let tfs = Native.Graphics.Input.passwords emptyFieldState
@@ -136,9 +172,10 @@ password placeHolder =
136172 in (lift (tfs.field id placeHolder) changes,
137173 dropRepeats (lift .string changes))
138174
139−-- Same as `field` but it adds an annotation that this field is for email
140−-- addresses. This is helpful for auto-complete and for mobile users who may
141−-- get a custom keyboard with an `@` and `.com` button.
175+{-| Same as `field` but it adds an annotation that this field is for email
176+addresses. This is helpful for auto-complete and for mobile users who may
177+get a custom keyboard with an `@` and `.com` button.
178+-}
142179email : String -> (Signal Element, Signal String)
143180email placeHolder =
144181 let tfs = Native.Graphics.Input.emails emptyFieldState
@@ -146,15 +183,17 @@ email placeHolder =
146183 in (lift (tfs.field id placeHolder) changes,
147184 dropRepeats (lift .string changes))
148185
149−-- Create a drop-down menu. When the user selects a string,
150−-- the current state of the drop-down is set to the associated
151−-- value. This lets you avoid manually mapping the string onto
152−-- functions and values.
186+{-| Create a drop-down menu. When the user selects a string,
187+the current state of the drop-down is set to the associated
188+value. This lets you avoid manually mapping the string onto
189+functions and values.
190+-}
153191dropDown : [(String,a)] -> (Signal Element, Signal a)
154192dropDown = Native.Graphics.Input.dropDown
155193
156−-- Create a drop-down menu for selecting strings. The resulting
157−-- signal of strings represents the string that is currently selected.
194+{-| Create a drop-down menu for selecting strings. The resulting
195+signal of strings represents the string that is currently selected.
196+-}
158197stringDropDown : [String] -> (Signal Element, Signal String)
159198stringDropDown strs =
160199 dropDown (List.map (\s -> (s,s)) strs)
libraries/List.elm+103−65
@@ -1,131 +1,162 @@
1−
21module List where
32
3+{-| A library for manipulating lists of values. Every value in a
4+list must have the same type.
5+
6+# Basics
7+@docs (::), (++), length, reverse, map
8+
9+# Sub-lists
10+@docs head, tail, last, filter, take, drop
11+
12+# Putting Lists Together
13+@docs concat, concatMap, join, intersperse, zip, zipWith
14+
15+# Taking Lists Apart
16+@docs split, partition, unzip
17+
18+# Folds
19+@docs foldr, foldl, foldr1, foldl1, scanl, scanl1
20+
21+# Special Folds
22+@docs susm, product, maximum, minimum, all, any, and, or
23+-}
24+
425import open Basics
526import Native.List
627
7−-- Add an element to the front of a list `(1 :: [2,3] == [1,2,3])`
28+{-| Add an element to the front of a list `(1 :: [2,3] == [1,2,3])` -}
829(::) : a -> [a] -> [a]
930(::) = Native.List.cons
1031
11−-- Puts two appendable things together:
12−--
13−-- [1,1] ++ [2,3] == [1,1,2,3]
14−-- "abc" ++ "123" == "abc123"
32+{-| Puts two appendable things together:
33+
34+ [1,1] ++ [2,3] == [1,1,2,3]
35+ "abc" ++ "123" == "abc123"
36+-}
1537(++) : appendable -> appendable -> appendable
1638(++) = Native.List.append
1739
18−-- Extract the first element of a list. List must be non-empty.
19−-- `(head [1,2,3] == 1)`
40+{-| Extract the first element of a list. List must be non-empty.
41+`(head [1,2,3] == 1)`
42+-}
2043head : [a] -> a
2144head = Native.List.head
2245
23−-- Extract the elements after the head of the list. List must be non-empty.
24−-- `(tail [1,2,3] == [2,3])`
46+{-| Extract the elements after the head of the list. List must be non-empty.
47+`(tail [1,2,3] == [2,3])`
48+-}
2549tail : [a] -> [a]
2650tail = Native.List.tail
2751
28−-- Extract the last element of a list. List must be non-empty.
29−-- `(last [1,2,3] == 3)`
52+{-| Extract the last element of a list. List must be non-empty.
53+`(last [1,2,3] == 3)`
54+-}
3055last : [a] -> a
3156last = Native.List.last
3257
33−-- Check if a list is empty `(isEmpty [] == True)`
58+{-| Check if a list is empty `(isEmpty [] == True)` -}
3459isEmpty : [a] -> Bool
3560isEmpty xs =
3661 case xs of
3762 [] -> True
3863 _ -> False
3964
40−-- Apply a function to every element of a list: `(map sqrt [1,4,9] == [1,2,3])`
65+{-| Apply a function to every element of a list: `(map sqrt [1,4,9] == [1,2,3])` -}
4166map : (a -> b) -> [a] -> [b]
4267map = Native.List.map
4368
44−-- Reduce a list from the left: `(foldl (::) [] "gateman" == "nametag")`
69+{-| Reduce a list from the left: `(foldl (::) [] "gateman" == "nametag")` -}
4570foldl : (a -> b -> b) -> b -> [a] -> b
4671foldl = Native.List.foldl
4772
48−-- Reduce a list from the right: `(foldr (+) 0 [1,2,3] == 6)`
73+{-| Reduce a list from the right: `(foldr (+) 0 [1,2,3] == 6)` -}
4974foldr : (a -> b -> b) -> b -> [a] -> b
5075foldr = Native.List.foldr
5176
52−-- Reduce a list from the left without a base case. List must be non-empty.
77+{-| Reduce a list from the left without a base case. List must be non-empty. -}
5378foldl1 : (a -> a -> a) -> [a] -> a
5479foldl1 = Native.List.foldl1
5580
56−-- Reduce a list from the right without a base case. List must be non-empty.
81+{-| Reduce a list from the right without a base case. List must be non-empty. -}
5782foldr1 : (a -> a -> a) -> [a] -> a
5883foldr1 = Native.List.foldr1
5984
60−-- Reduce a list from the left, building up all of the intermediate results into a list.
61−--
62−-- scanl (+) 0 [1,2,3,4] == [0,1,3,6,10]
85+{-| Reduce a list from the left, building up all of the intermediate results into a list.
86+
87+ scanl (+) 0 [1,2,3,4] == [0,1,3,6,10]
88+-}
6389scanl : (a -> b -> b) -> b -> [a] -> [b]
6490scanl = Native.List.scanl
6591
66−-- Same as scanl but it doesn't require a base case. List must be non-empty.
67−--
68−-- scanl1 (+) [1,2,3,4] == [1,3,6,10]
92+{-| Same as scanl but it doesn't require a base case. List must be non-empty.
93+
94+ scanl1 (+) [1,2,3,4] == [1,3,6,10]
95+-}
6996scanl1 : (a -> a -> a) -> [a] -> [a]
7097scanl1 = Native.List.scanl1
7198
72−-- Filter out elements which do not satisfy the predicate: `(filter isLower "AaBbCc" == "abc")`
99+{-| Keep only elements that satisfy the predicate:
100+`(filter isLower "AaBbCc" == "abc")`
101+-}
73102filter : (a -> Bool) -> [a] -> [a]
74103filter = Native.List.filter
75104
76−-- Determine the length of a list: `(length "innumerable" == 11)`
105+{-| Determine the length of a list: `(length "innumerable" == 11)` -}
77106length : [a] -> Int
78107length = Native.List.length
79108
80−-- Reverse a list. `(reverse [1..4] == [4,3,2,1])`
109+{-| Reverse a list. `(reverse [1..4] == [4,3,2,1])` -}
81110reverse : [a] -> [a]
82111reverse = Native.List.reverse
83112
84−-- Check to see if all elements satisfy the predicate.
113+{-| Check to see if all elements satisfy the predicate. -}
85114all : (a -> Bool) -> [a] -> Bool
86115all = Native.List.all
87116
88−-- Check to see if any elements satisfy the predicate.
117+{-| Check to see if any elements satisfy the predicate. -}
89118any : (a -> Bool) -> [a] -> Bool
90119any = Native.List.any
91120
92−-- Check to see if all elements are True.
121+{-| Check to see if all elements are True. -}
93122and : [Bool] -> Bool
94123and = foldl (&&) True
95124
96−-- Check to see if any elements are True.
125+{-| Check to see if any elements are True. -}
97126or : [Bool] -> Bool
98127or = foldl (||) False
99128
100−-- Concatenate a list of appendable things:
101−--
102−-- concat ["tree","house"] == "treehouse"
129+{-| Concatenate a list of appendable things:
130+
131+ concat ["tree","house"] == "treehouse"
132+-}
103133concat : [appendable] -> appendable
104134concat = Native.List.concat
105135
106−-- Map a given function onto a list and flatten the resulting lists.
107−--
108−-- concatMap f xs == concat (map f xs)
136+{-| Map a given function onto a list and flatten the resulting lists.
137+
138+ concatMap f xs == concat (map f xs)
139+-}
109140concatMap : (a -> appendable) -> [a] -> appendable
110141concatMap f list = concat (map f list)
111142
112−-- Get the sum of the list elements. `(sum [1..4] == 10)`
143+{-| Get the sum of the list elements. `(sum [1..4] == 10)` -}
113144sum : [number] -> number
114145sum = foldl (+) 0
115146
116−-- Get the product of the list elements. `(product [1..4] == 24)`
147+{-| Get the product of the list elements. `(product [1..4] == 24)` -}
117148product : [number] -> number
118149product = foldl (*) 1
119150
120−-- Find the maximum element in a non-empty list: `maximum [1,4,2] == 4`
151+{-| Find the maximum element in a non-empty list: `maximum [1,4,2] == 4` -}
121152maximum : [comparable] -> comparable
122153maximum = foldl1 max
123154
124−-- Find the minimum element in a non-empty list: `minimum [3,2,1] == 1`
155+{-| Find the minimum element in a non-empty list: `minimum [3,2,1] == 1` -}
125156minimum : [comparable] -> comparable
126157minimum = foldl1 min
127158
128−-- Split a list based on the predicate.
159+{-| Split a list based on the predicate. -}
129160partition : (a -> Bool) -> [a] -> ([a],[a])
130161partition pred lst =
131162 case lst of
@@ -133,44 +164,49 @@ partition pred lst =
133164 x::xs -> let (bs,cs) = partition pred xs in
134165 if pred x then (x::bs,cs) else (bs,x::cs)
135166
136−-- Combine two lists, combining them into tuples pairwise.
137−-- If one list is longer, the extra elements are dropped.
138−--
139−-- zip [1,2,3] [6,7] == [(1,6),(2,7)]
140−-- zip == zipWith (,)
167+{-| Combine two lists, combining them into tuples pairwise.
168+If one list is longer, the extra elements are dropped.
169+
170+ zip [1,2,3] [6,7] == [(1,6),(2,7)]
171+ zip == zipWith (,)
172+-}
141173zip : [a] -> [b] -> [(a,b)]
142174zip = Native.List.zip
143175
144−-- Combine two lists, combining them with the given function.
145−-- If one list is longer, the extra elements are dropped.
146−--
147−-- zipWith (+) [1,2,3] [1,2,3,4] == [2,4,6]
176+{-| Combine two lists, combining them with the given function.
177+If one list is longer, the extra elements are dropped.
178+
179+ zipWith (+) [1,2,3] [1,2,3,4] == [2,4,6]
180+-}
148181zipWith : (a -> b -> c) -> [a] -> [b] -> [c]
149182zipWith = Native.List.zipWith
150183
151−-- Decompose a list of tuples.
184+{-| Decompose a list of tuples. -}
152185unzip : [(a,b)] -> ([a],[b])
153186unzip pairs =
154187 case pairs of
155188 [] -> ([],[])
156189 (x,y)::ps -> let (xs,ys) = (unzip ps) in (x::xs,y::ys)
157190
158−-- Split a list with a given seperator.
159−--
160−-- split "," "hello,there,friend" == ["hello", "there", "friend"]
191+{-| Split a list with a given seperator.
192+
193+ split "," "hello,there,friend" == ["hello", "there", "friend"]
194+-}
161195split : [a] -> [a] -> [[a]]
162196split = Native.List.split
163197
164−-- Places the given value between all of the lists in the second argument
165−-- and concatenates the result.
166−--
167−-- join "a" ["H","w","ii","n"] == "Hawaiian"
198+{-| Places the given value between all of the lists in the second
199+argument and concatenates the result.
200+
201+ join "a" ["H","w","ii","n"] == "Hawaiian"
202+-}
168203join : appendable -> [appendable] -> appendable
169204join = Native.List.join
170205
171−-- Places the given value between all members of the given list.
172−--
173−-- intersperse ' ' "INCEPTION" == "I N C E P T I O N"
206+{-| Places the given value between all members of the given list.
207+
208+ intersperse ' ' "INCEPTION" == "I N C E P T I O N"
209+-}
174210intersperse : a -> [a] -> [a]
175211intersperse sep xs =
176212 case xs of
@@ -178,14 +214,16 @@ intersperse sep xs =
178214 [a] -> [a]
179215 [] -> []
180216
181−-- Take the first n members of a list: `(take 2 [1,2,3,4] == [1,2])`
217+{-| Take the first n members of a list: `(take 2 [1,2,3,4] == [1,2])` -}
182218take : Int -> [a] -> [a]
183219take = Native.List.take
184220
185−-- Drop the first n members of a list: `(drop 2 [1,2,3,4] == [3,4])`
221+{-| Drop the first n members of a list: `(drop 2 [1,2,3,4] == [3,4])` -}
186222drop : Int -> [a] -> [a]
187223drop = Native.List.drop
188224
189−-- Creates a list with n copies of a value: `(replicate 3 (0,0) == [(0,0),(0,0),(0,0)]`
225+{-| Creates a list with *n* copies of a value:
226+`(repeat 3 (0,0) == [(0,0),(0,0),(0,0)]`
227+-}
190228repeat : Int -> a -> [a]
191229repeat = Native.List.repeat