on master help sign in
Merge branch 'master' into dev
d8ced9eEvan Czaplicki
Elm.cabal+3−3
@@ -1,5 +1,5 @@
1Name: Elm
1Name: Elm
2−Version: 0.9.0.2
2+Version: 0.10.0.2
3Synopsis: The Elm language module.
3Synopsis: The Elm language module.
4Description: Elm aims to make client-side web-development more pleasant.
4Description: Elm aims to make client-side web-development more pleasant.
5 It is a statically/strongly typed, functional reactive
5 It is a statically/strongly typed, functional reactive
@@ -88,7 +88,7 @@ Library
88 directory,
88 directory,
89 filepath,
89 filepath,
90 indents,
90 indents,
91− language-ecmascript,
91+ language-ecmascript < 1,
92 mtl >= 2,
92 mtl >= 2,
93 pandoc >= 1.10,
93 pandoc >= 1.10,
94 parsec >= 3.1.1,
94 parsec >= 3.1.1,
@@ -157,7 +157,7 @@ Executable elm
157 directory,
157 directory,
158 filepath,
158 filepath,
159 indents,
159 indents,
160− language-ecmascript,
160+ language-ecmascript < 1,
161 mtl >= 2,
161 mtl >= 2,
162 pandoc >= 1.10,
162 pandoc >= 1.10,
163 parsec >= 3.1.1,
163 parsec >= 3.1.1,
README.md+4−5
@@ -3,8 +3,7 @@ Learn about the Elm programming language at [elm-lang.org](http://elm-lang.org/)
3
3
4## Install
4## Install
5
5
6−Download the [Haskell Platform 2012.2.0.0](http://hackage.haskell.org/platform/).
6+Download the [Haskell Platform 2012.2.0.0 or later](http://hackage.haskell.org/platform/).
7−Elm definitely works with GHC 7.4, so newer versions of the Haskell Platform may work too.
8Once the Haskell Platform is installed:
7Once the Haskell Platform is installed:
9
8
10 cabal update
9 cabal update
@@ -39,10 +38,10 @@ commands place a simple program into `Main.elm`. Do this manually if you do not
39have `printf`. The final command starts the Elm server at [localhost:8000](http://localhost:8000/),
38have `printf`. The final command starts the Elm server at [localhost:8000](http://localhost:8000/),
40allowing you to navigate to `Main.elm` and see your first program in action.
39allowing you to navigate to `Main.elm` and see your first program in action.
41
40
42−#### Wrap up
41+#### Final Notes
43
42
44−The `elm` package provides support for compilation of Elm code directly in Haskell and QuasiQuoting.
43+The `elm` package provides support for compilation of Elm code directly in Haskell.
45−Check it out on Hackage if you are interested.
44+Check it out [on Hackage](http://hackage.haskell.org/package/Elm) if you are interested.
46
45
47If you are stuck, email [the list](https://groups.google.com/forum/?fromgroups#!forum/elm-discuss)
46If you are stuck, email [the list](https://groups.google.com/forum/?fromgroups#!forum/elm-discuss)
48or ask a question in the [#Elm IRC channel](http://webchat.freenode.net/?channels=elm).
47or ask a question in the [#Elm IRC channel](http://webchat.freenode.net/?channels=elm).
compiler/Generate/JavaScript.hs+15−9
@@ -243,14 +243,17 @@ match :: (Show a) => a -> Case.Match () () -> State Int [Statement ()]
243match span mtch =
243match span mtch =
244 case mtch of
244 case mtch of
245 Case.Match name clauses mtch' ->
245 Case.Match name clauses mtch' ->
246− do clauses' <- mapM (clause span name) clauses
246+ do (isChars, clauses') <- unzip <$> mapM (clause span name) clauses
247 mtch'' <- match span mtch'
247 mtch'' <- match span mtch'
248− return (SwitchStmt () (access name) clauses' : mtch'')
248+ return (SwitchStmt () (format isChars (access name)) clauses' : mtch'')
249 where
249 where
250 isLiteral p = case p of
250 isLiteral p = case p of
251 Case.Clause (Right _) _ _ -> True
251 Case.Clause (Right _) _ _ -> True
252 _ -> False
252 _ -> False
253 access name = if any isLiteral clauses then ref name else dotSep [name,"ctor"]
253 access name = if any isLiteral clauses then ref name else dotSep [name,"ctor"]
254+ format isChars e
255+ | or isChars = InfixExpr () OpAdd e (string "")
256+ | otherwise = e
254
257
255 Case.Fail ->
258 Case.Fail ->
256 return [ ExprStmt () (obj "_E.Case" `call` [ref "$moduleName", string (show span)]) ]
259 return [ ExprStmt () (obj "_E.Case" `call` [ref "$moduleName", string (show span)]) ]
@@ -268,15 +271,18 @@ match span mtch =
268 _ -> dropEnd (acc ++ [m]) ms
271 _ -> dropEnd (acc ++ [m]) ms
269
272
270clause span variable (Case.Clause value vars mtch) =
273clause span variable (Case.Clause value vars mtch) =
271− CaseClause () pattern <$> match span (Case.matchSubst (zip vars vars') mtch)
274+ (,) isChar . CaseClause () pattern <$> match span (Case.matchSubst (zip vars vars') mtch)
272 where
275 where
273 vars' = map (\n -> variable ++ "._" ++ show n) [0..]
276 vars' = map (\n -> variable ++ "._" ++ show n) [0..]
277+ (isChar, pattern) =
278+ case value of
279+ Right (Chr c) -> (True, string [c])
274− pattern = case value of
280+ _ -> (,) False $ case value of
275− Right (Boolean b) -> BoolLit () b
281+ Right (Boolean b) -> BoolLit () b
276− Right lit -> literal lit
282+ Right lit -> literal lit
277− Left name -> string $ case List.elemIndices '.' name of
283+ Left name -> string $ case List.elemIndices '.' name of
278− [] -> name
284+ [] -> name
279− is -> drop (last is + 1) name
285+ is -> drop (last is + 1) name
280
286
281
287
282jsModule :: MetadataModule () () -> String
288jsModule :: MetadataModule () () -> String
compiler/Parse/Type.hs+13−10
@@ -25,19 +25,22 @@ tuple = do ts <- parens (commaSep expr)
25record :: IParser T.Type
25record :: IParser T.Type
26record =
26record =
27 do char '{' ; whitespace
27 do char '{' ; whitespace
28− ext <- extend
28+ (ext,fs) <- extended <|> normal
29− fs <- fields
30 dumbWhitespace ; char '}'
29 dumbWhitespace ; char '}'
31 return (T.Record fs ext)
30 return (T.Record fs ext)
32 where
31 where
33− extend = option T.EmptyRecord . try $ do
32+ normal = (,) T.EmptyRecord <$> commaSep fields
34− t <- tvar
33+
34+ -- extended record types require at least one field
35+ extended = do
35− whitespace >> string "|" >> whitespace
36+ ext <- try (const <$> tvar <*> (whitespace >> string "|"))
36− return t
37+ whitespace
37− fields = commaSep1 $ do
38+ (,) ext <$> commaSep1 fields
39+
40+ fields = do
38− lbl <- rLabel
41+ lbl <- rLabel
39− whitespace >> hasType >> whitespace
42+ whitespace >> hasType >> whitespace
40− (,) lbl <$> expr
43+ (,) lbl <$> expr
41
44
42capTypeVar = intercalate "." <$> dotSep1 capVar
45capTypeVar = intercalate "." <$> dotSep1 capVar
43
46
compiler/SourceSyntax/Declaration.hs+24−1
@@ -4,6 +4,8 @@ module SourceSyntax.Declaration where
4import Data.Data
4import Data.Data
5import qualified SourceSyntax.Expression as Expr
5import qualified SourceSyntax.Expression as Expr
6import SourceSyntax.Type
6import SourceSyntax.Type
7+import SourceSyntax.PrettyPrint
8+import Text.PrettyPrint as P
7
9
8data Declaration tipe var
10data Declaration tipe var
9 = Definition (Expr.Def tipe var)
11 = Definition (Expr.Def tipe var)
@@ -22,4 +24,25 @@ instance Show Assoc where
22 case assoc of
24 case assoc of
23 L -> "left"
25 L -> "left"
24 N -> "non"
26 N -> "non"
25− R -> "right"
27+ R -> "right"
28+
29+instance Pretty (Declaration t v) where
30+ pretty decl =
31+ case decl of
32+ Definition def -> pretty def
33+
34+ Datatype tipe tvars ctors ->
35+ P.hang (P.text "data" <+> P.text tipe <+> P.hsep (map P.text tvars)) 4
36+ (P.sep $ zipWith join ("=" : repeat "|") ctors)
37+ where
38+ join c ctor = P.text c <+> prettyCtor ctor
39+ prettyCtor (name, tipes) =
40+ P.hang (P.text name) 2 (P.sep (map prettyParens tipes))
41+
42+ TypeAlias name tvars tipe ->
43+ let alias = P.text name <+> P.hsep (map P.text tvars) in
44+ P.hang (P.text "type" <+> alias <+> P.equals) 4 (pretty tipe)
45+
46+ -- TODO: actually write out the other cases. They are currently unused, but
47+ -- this is probably going to be a bug someday.
48+ _ -> P.text (show decl)
compiler/Transform/Check.hs+46−2
@@ -2,9 +2,11 @@ module Transform.Check (mistakes) where
2
2
3import Transform.SortDefinitions (boundVars)
3import Transform.SortDefinitions (boundVars)
4import SourceSyntax.Everything
4import SourceSyntax.Everything
5+import SourceSyntax.PrettyPrint
5import qualified SourceSyntax.Type as T
6import qualified SourceSyntax.Type as T
6import Data.List as List
7import Data.List as List
7import qualified Data.Map as Map
8import qualified Data.Map as Map
9+import qualified Data.Maybe as Maybe
8import qualified Data.Set as Set
10import qualified Data.Set as Set
9import Data.Data
11import Data.Data
10import Data.Generics.Uniplate.Data
12import Data.Generics.Uniplate.Data
@@ -13,7 +15,7 @@ import Text.PrettyPrint as P
13
15
14mistakes :: (Data t, Data v) => [Declaration t v] -> [Doc]
16mistakes :: (Data t, Data v) => [Declaration t v] -> [Doc]
15mistakes decls =
17mistakes decls =
16− map P.text $ concatMap findErrors (getLets decls)
18+ illFormedTypes decls ++ map P.text (concatMap findErrors (getLets decls))
17 where
19 where
18 findErrors defs = duplicates defs ++ badOrder defs
20 findErrors defs = duplicates defs ++ badOrder defs
19
21
@@ -60,4 +62,46 @@ badOrder defs = go defs
60
62
61 _ -> []
63 _ -> []
62
64
63−
65+illFormedTypes :: [Declaration t v] -> [Doc]
66+illFormedTypes decls = map report (Maybe.mapMaybe isIllFormed (aliases ++ adts))
67+ where
68+ aliases = [ (decl, tvars, [tipe]) | decl@(TypeAlias _ tvars tipe) <- decls ]
69+ adts = [ (decl, tvars, concatMap snd ctors) | decl@(Datatype _ tvars ctors) <- decls ]
70+
71+ freeVars tipe =
72+ case tipe of
73+ T.Lambda t1 t2 -> Set.union (freeVars t1) (freeVars t2)
74+ T.Var x -> Set.singleton x
75+ T.Data _ ts -> Set.unions (map freeVars ts)
76+ T.EmptyRecord -> Set.empty
77+ T.Record fields ext -> Set.unions (freeVars ext : map (freeVars . snd) fields)
78+
79+ undeclared tvars tipes = Set.difference used declared
80+ where
81+ used = Set.unions (map freeVars tipes)
82+ declared = Set.fromList tvars
83+
84+ isIllFormed (decl, tvars, tipes) =
85+ let unbound = undeclared tvars tipes in
86+ if Set.null unbound then Nothing
87+ else Just (decl, Set.toList unbound)
88+
89+ report (decl, tvars) =
90+ P.vcat [ P.text $ "Error: type variable" ++ listing ++ " unbound in:"
91+ , P.text "\n"
92+ , nest 4 (pretty decl) ]
93+ where
94+ listing =
95+ case tvars of
96+ [tvar] -> " " ++ quote tvar ++ " is"
97+ _ -> "s" ++ addCommas (map ((++) " ") (addAnd (map quote tvars))) ++ " are"
98+
99+ addCommas xs
100+ | length xs < 3 = concat xs
101+ | otherwise = intercalate "," xs
102+
103+ addAnd xs
104+ | length xs < 2 = xs
105+ | otherwise = zipWith (++) (replicate (length xs - 1) "" ++ ["and "]) xs
106+
107+ quote tvar = "'" ++ tvar ++ "'"
libraries/AutomatonV2.elm → libraries/AutomatonV2.elm.hiddenrenamed

The content is the same.

libraries/Color.elm+1−1
@@ -6,7 +6,7 @@ module Color where
6built-in names.
6built-in names.
7
7
8# Creation
8# Creation
9−@docs rgb, rgba, hsv, hsva, grayscale, greyscale
9+@docs rgb, rgba, hsv, hsva, greyscale, grayscale
10
10
11# From Other Colors
11# From Other Colors
12@docs complement
12@docs complement
libraries/Either.elm−12
@@ -52,28 +52,16 @@ have the equivalence: `(partition es == (lefts es, rights es))`
52partition : [Either a b] -> ([a],[b])
52partition : [Either a b] -> ([a],[b])
53partition es = List.foldr consEither ([],[]) es
53partition es = List.foldr consEither ([],[]) es
54
54
55−{-| If `Left`, add the value to the front of the list.
56−If `Right`, return the list unchanged
57−-}
58−consLeft : Either a b -> [a] -> [a]
59consLeft e vs =
55consLeft e vs =
60 case e of
56 case e of
61 Left v -> v::vs
57 Left v -> v::vs
62 Right _ -> vs
58 Right _ -> vs
63
59
64−{-| If `Right`, add the value to the front of the list.
65−If `Left`, return the list unchanged.
66−-}
67−consRight : Either a b -> [b] -> [b]
68consRight e vs =
60consRight e vs =
69 case e of
61 case e of
70 Left _ -> vs
62 Left _ -> vs
71 Right v -> v::vs
63 Right v -> v::vs
72
64
73−{-| If `Left`, add the value to the left list.
74−If `Right`, add the value to the right list.
75−-}
76−consEither : Either a b -> ([a], [b]) -> ([a], [b])
77consEither e (ls,rs) =
65consEither e (ls,rs) =
78 case e of
66 case e of
79 Left l -> (l::ls,rs)
67 Left l -> (l::ls,rs)
libraries/Graphics/Collage.elm+11−11
@@ -125,7 +125,7 @@ tiled to fill the entire shape.
125textured : String -> Shape -> Form
125textured : String -> Shape -> Form
126textured src shape = fill (Texture src) shape
126textured src shape = fill (Texture src) shape
127
127
128−{-| Fill a shape with a [gradient](/docs/Color.elm#linear). -}
128+{-| Fill a shape with a [gradient](/library/Color.elm#linear). -}
129gradient : Gradient -> Shape -> Form
129gradient : Gradient -> Shape -> Form
130gradient grad shape = fill (Grad grad) shape
130gradient grad shape = fill (Grad grad) shape
131
131
@@ -204,37 +204,37 @@ collage : Int -> Int -> [Form] -> Element
204collage = Native.Graphics.Collage.collage
204collage = Native.Graphics.Collage.collage
205
205
206
206
207−type Path = [(number,number)]
207+type Path = [(Float,Float)]
208
208
209{-| Create a path that follows a sequence of points. -}
209{-| Create a path that follows a sequence of points. -}
210−path : [(number,number)] -> Path
210+path : [(Float,Float)] -> Path
211path ps = ps
211path ps = ps
212
212
213{-| Create a path along a given line segment. -}
213{-| Create a path along a given line segment. -}
214−segment : (number,number) -> (number,number) -> Path
214+segment : (Float,Float) -> (Float,Float) -> Path
215segment p1 p2 = [p1,p2]
215segment p1 p2 = [p1,p2]
216
216
217−type Shape = [(number,number)]
217+type Shape = [(Float,Float)]
218
218
219{-| Create an arbitrary polygon by specifying its corners in order.
219{-| Create an arbitrary polygon by specifying its corners in order.
220`polygon` will automatically close all shapes, so the given list
220`polygon` will automatically close all shapes, so the given list
221of points does not need to start and end with the same position.
221of points does not need to start and end with the same position.
222-}
222-}
223−polygon : [(number,number)] -> Shape
223+polygon : [(Float,Float)] -> Shape
224polygon points = points
224polygon points = points
225
225
226{-| A rectangle with a given width and height. -}
226{-| A rectangle with a given width and height. -}
227−rect : number -> number -> Shape
227+rect : Float -> Float -> Shape
228rect w h = let hw = w/2
228rect w h = let hw = w/2
229 hh = h/2
229 hh = h/2
230 in [ (0-hw,0-hh), (0-hw,hh), (hw,hh), (hw,0-hh) ]
230 in [ (0-hw,0-hh), (0-hw,hh), (hw,hh), (hw,0-hh) ]
231
231
232{-| A square with a given edge length. -}
232{-| A square with a given edge length. -}
233−square : number -> Shape
233+square : Float -> Shape
234square n = rect n n
234square n = rect n n
235
235
236{-| An oval with a given width and height. -}
236{-| An oval with a given width and height. -}
237−oval : number -> number -> Shape
237+oval : Float -> Float -> Shape
238oval w h =
238oval w h =
239 let n = 50
239 let n = 50
240 t = 2 * pi / n
240 t = 2 * pi / n
@@ -244,7 +244,7 @@ oval w h =
244 in List.map f [0..n-1]
244 in List.map f [0..n-1]
245
245
246{-| A circle with a given radius. -}
246{-| A circle with a given radius. -}
247−circle : number -> Shape
247+circle : Float -> Shape
248circle r = oval (2*r) (2*r)
248circle r = oval (2*r) (2*r)
249
249
250{-| A regular polygon with N sides. The first argument specifies the number
250{-| A regular polygon with N sides. The first argument specifies the number
@@ -253,7 +253,7 @@ of sides and the second is the radius. So to create a pentagon with radius
253
253
254 ngon 5 30
254 ngon 5 30
255-}
255-}
256−ngon : Int -> number -> Shape
256+ngon : Int -> Float -> Shape
257ngon n r =
257ngon n r =
258 let m = toFloat n
258 let m = toFloat n
259 t = 2 * pi / m
259 t = 2 * pi / m
libraries/Graphics/Element.elm+7−8
@@ -204,9 +204,8 @@ flow dir es =
204 DIn -> newFlow (List.maximum ws) (List.maximum hs)
204 DIn -> newFlow (List.maximum ws) (List.maximum hs)
205 DOut -> newFlow (List.maximum ws) (List.maximum hs)
205 DOut -> newFlow (List.maximum ws) (List.maximum hs)
206
206
207−{-| Stack elements vertically. To put `a` above `b` you would say:
207+{-| Stack elements vertically.
208−
208+To put `a` above `b` you would say: ``a `above` b``
209− a `above` b
210-}
209-}
211above : Element -> Element -> Element
210above : Element -> Element -> Element
212above hi lo =
211above hi lo =
@@ -214,9 +213,8 @@ above hi lo =
214 (heightOf hi + heightOf lo)
213 (heightOf hi + heightOf lo)
215 (Flow DDown [hi,lo])
214 (Flow DDown [hi,lo])
216
215
217−{-| Stack elements vertically. To put `a` below `b` you would say:
216+{-| Stack elements vertically.
218−
217+To put `a` below `b` you would say: ``a `below` b``
219− a `below` b
220-}
218-}
221below : Element -> Element -> Element
219below : Element -> Element -> Element
222below lo hi =
220below lo hi =
@@ -225,6 +223,7 @@ below lo hi =
225 (Flow DDown [hi,lo])
223 (Flow DDown [hi,lo])
226
224
227{-| Put elements beside each other horizontally.
225{-| Put elements beside each other horizontally.
226+To put `a` beside `b` you would say: ``a `beside` b``
228-}
227-}
229beside : Element -> Element -> Element
228beside : Element -> Element -> Element
230beside lft rht =
229beside lft rht =
@@ -232,8 +231,8 @@ beside lft rht =
232 (max (heightOf lft) (heightOf rht))
231 (max (heightOf lft) (heightOf rht))
233 (Flow right [lft,rht])
232 (Flow right [lft,rht])
234
233
235−{-| Layer elements on top of each other, starting from the bottom.
234+{-| Layer elements on top of each other, starting from the bottom:
236−`(layers == flow outward)`
235+`layers == flow outward`
237-}
236-}
238layers : [Element] -> Element
237layers : [Element] -> Element
239layers es =
238layers es =
libraries/JavaScript.elm+1−1
@@ -9,7 +9,7 @@ integration.
9@docs toString, toInt, toFloat, toBool, toList
9@docs toString, toInt, toFloat, toBool, toList
10
10
11# JavaScript from Elm
11# JavaScript from Elm
12−@docs fromString, fromInt, fromFloat, fromBool fromList
12+@docs fromString, fromInt, fromFloat, fromBool, fromList
13-}
13-}
14{-
14{-
15# DOM Nodes and Elements
15# DOM Nodes and Elements
libraries/Maybe.elm−5
@@ -39,11 +39,6 @@ isJust = maybe False (\_ -> True)
39isNothing : Maybe a -> Bool
39isNothing : Maybe a -> Bool
40isNothing = not . isJust
40isNothing = not . isJust
41
41
42−
43−{-| If `Just`, adds the value to the front of the list.
44−If `Nothing`, list is unchanged.
45−-}
46−cons : Maybe a -> [a] -> [a]
47cons mx xs = maybe xs (\x -> x :: xs) mx
42cons mx xs = maybe xs (\x -> x :: xs) mx
48
43
49{-| Filters out Nothings and extracts the remaining values.
44{-| Filters out Nothings and extracts the remaining values.
libraries/Native/Basics.js+1−1
@@ -33,7 +33,7 @@ Elm.Native.Basics.make = function(elm) {
33 mod:mod,
33 mod:mod,
34
34
35 pi:Math.PI,
35 pi:Math.PI,
36− e:Math.e,
36+ e:Math.E,
37 cos:Math.cos,
37 cos:Math.cos,
38 sin:Math.sin,
38 sin:Math.sin,
39 tan:Math.tan,
39 tan:Math.tan,
libraries/Native/Show.js+1−1
@@ -21,7 +21,7 @@ Elm.Native.Show.make = function(elm) {
21 return v ? "True" : "False";
21 return v ? "True" : "False";
22 } else if (type === "number") {
22 } else if (type === "number") {
23 return v+"";
23 return v+"";
24− } else if (v.isChar && v instanceof String) {
24+ } else if ((v instanceof String) && v.isChar) {
25 return "'" + addSlashes(v) + "'";
25 return "'" + addSlashes(v) + "'";
26 } else if (type === "string") {
26 } else if (type === "string") {
27 return '"' + addSlashes(v) + '"';
27 return '"' + addSlashes(v) + '"';
libraries/Native/Signal/Http.js+3−4
@@ -26,10 +26,6 @@ Elm.Native.Http.make = function(elm) {
26 }
26 }
27 }
27 }
28
28
29− function setHeader(pair) {
30− request.setRequestHeader( JS.fromString(pair._0), JS.fromString(pair._1) );
31− }
32−
33 function sendReq(queue,responses,req) {
29 function sendReq(queue,responses,req) {
34 var response = { value: { ctor:'Waiting' } };
30 var response = { value: { ctor:'Waiting' } };
35 queue.push(response);
31 queue.push(response);
@@ -46,6 +42,9 @@ Elm.Native.Http.make = function(elm) {
46 }
42 }
47 };
43 };
48 request.open(JS.fromString(req.verb), JS.fromString(req.url), true);
44 request.open(JS.fromString(req.verb), JS.fromString(req.url), true);
45+ function setHeader(pair) {
46+ request.setRequestHeader( JS.fromString(pair._0), JS.fromString(pair._1) );
47+ }
49 List.map(setHeader)(req.headers);
48 List.map(setHeader)(req.headers);
50 request.send(JS.fromString(req.body));
49 request.send(JS.fromString(req.body));
51 }
50 }
libraries/Native/String.js+29−10
@@ -22,14 +22,24 @@ Elm.Native.String.make = function(elm) {
22 return (hd = str[0]) ? Maybe.Just(Utils.Tuple2(Utils.chr(hd), str.slice(1)))
22 return (hd = str[0]) ? Maybe.Just(Utils.Tuple2(Utils.chr(hd), str.slice(1)))
23 : Maybe.Nothing;
23 : Maybe.Nothing;
24 }
24 }
25+ function append(a,b) {
26+ return a + b;
27+ }
28+ function concat(strs) {
29+ return JS.fromList(strs).join('');
30+ }
25 function length(str) {
31 function length(str) {
26 return str.length;
32 return str.length;
27 }
33 }
28 function map(f,str) {
34 function map(f,str) {
29− return str.split('').map(f).join('');
35+ var out = str.split('');
36+ for (var i = out.length; i--; ) {
37+ out[i] = f(Utils.chr(out[i]));
38+ }
39+ return out.join('');
30 }
40 }
31 function filter(pred,str) {
41 function filter(pred,str) {
32− return str.split('').filter(pred).join('');
42+ return str.split('').map(Utils.chr).filter(pred).join('');
33 }
43 }
34 function reverse(str) {
44 function reverse(str) {
35 return str.split('').reverse().join('');
45 return str.split('').reverse().join('');
@@ -37,13 +47,13 @@ Elm.Native.String.make = function(elm) {
37 function foldl(f,b,str) {
47 function foldl(f,b,str) {
38 var len = str.length;
48 var len = str.length;
39 for (var i = 0; i < len; ++i) {
49 for (var i = 0; i < len; ++i) {
40− b = A2(f, str[i], b);
50+ b = A2(f, Utils.chr(str[i]), b);
41 }
51 }
42 return b;
52 return b;
43 }
53 }
44 function foldr(f,b,str) {
54 function foldr(f,b,str) {
45 for (var i = str.length; i--; ) {
55 for (var i = str.length; i--; ) {
46− b = A2(f, str[i], b);
56+ b = A2(f, Utils.chr(str[i]), b);
47 }
57 }
48 return b;
58 return b;
49 }
59 }
@@ -116,13 +126,13 @@ Elm.Native.String.make = function(elm) {
116
126
117 function any(pred, str) {
127 function any(pred, str) {
118 for (var i = str.length; i--; ) {
128 for (var i = str.length; i--; ) {
119− if (pred(str[i])) return true;
129+ if (pred(Utils.chr(str[i]))) return true;
120 }
130 }
121 return false;
131 return false;
122 }
132 }
123 function all(pred, str) {
133 function all(pred, str) {
124 for (var i = str.length; i--; ) {
134 for (var i = str.length; i--; ) {
125− if (!pred(str[i])) return false;
135+ if (!pred(Utils.chr(str[i]))) return false;
126 }
136 }
127 return true;
137 return true;
128 }
138 }
@@ -147,8 +157,7 @@ Elm.Native.String.make = function(elm) {
147 return JS.toList(is);
157 return JS.toList(is);
148 }
158 }
149
159
150− function toInt(str) {
160+ function toInt(s) {
151− var s = JS.fromString(str);
152 var len = s.length;
161 var len = s.length;
153 if (len === 0) { return Maybe.Nothing; }
162 if (len === 0) { return Maybe.Nothing; }
154 var start = 0;
163 var start = 0;
@@ -162,8 +171,7 @@ Elm.Native.String.make = function(elm) {
162 return Maybe.Just(parseInt(s, 10));
171 return Maybe.Just(parseInt(s, 10));
163 }
172 }
164
173
165− function toFloat(str) {
174+ function toFloat(s) {
166− var s = JS.fromString(str);
167 var len = s.length;
175 var len = s.length;
168 if (len === 0) { return Maybe.Nothing; }
176 if (len === 0) { return Maybe.Nothing; }
169 var start = 0;
177 var start = 0;
@@ -183,10 +191,19 @@ Elm.Native.String.make = function(elm) {
183 return Maybe.Just(parseFloat(s));
191 return Maybe.Just(parseFloat(s));
184 }
192 }
185
193
194+ function toList(str) {
195+ return JS.toList(str.split('').map(Utils.chr));
196+ }
197+ function fromList(chars) {
198+ return JS.fromList(chars).join('');
199+ }
200+
186 return Elm.Native.String.values = {
201 return Elm.Native.String.values = {
187 isEmpty: isEmpty,
202 isEmpty: isEmpty,
188 cons: F2(cons),
203 cons: F2(cons),
189 uncons: uncons,
204 uncons: uncons,
205+ append: F2(append),
206+ concat: concat,
190 length: length,
207 length: length,
191 map: F2(map),
208 map: F2(map),
192 filter: F2(filter),
209 filter: F2(filter),
@@ -228,5 +245,7 @@ Elm.Native.String.make = function(elm) {
228
245
229 toInt: toInt,
246 toInt: toInt,
230 toFloat: toFloat,
247 toFloat: toFloat,
248+ toList: toList,
249+ fromList: fromList,
231 };
250 };
232};
251};
libraries/Random.elm+1−1
@@ -3,7 +3,7 @@ module Random where
3{-| Since the core of Elm is pure, randomness must be handled via signals.
3{-| Since the core of Elm is pure, randomness must be handled via signals.
4
4
5# Random Numbers
5# Random Numbers
6−@docs range, float
6+@docs range, float, floatList
7-}
7-}
8
8
9import Signal (Signal)
9import Signal (Signal)
libraries/Signal.elm+3−3
@@ -15,15 +15,15 @@ the [`Time`](/docs/Signal/Time.elm) library.
15# Combine
15# Combine
16@docs constant, lift, lift2, merge, merges, combine
16@docs constant, lift, lift2, merge, merges, combine
17
17
18−# Pretty Lift
19−@docs (<~), (~)
20−
21# Past-Dependence
18# Past-Dependence
22@docs foldp, count, countIf
19@docs foldp, count, countIf
23
20
24#Filters
21#Filters
25@docs keepIf, dropIf, keepWhen, dropWhen, dropRepeats, sampleOn
22@docs keepIf, dropIf, keepWhen, dropWhen, dropRepeats, sampleOn
26
23
24+# Pretty Lift
25+@docs (<~), (~)
26+
27# Do you even lift?
27# Do you even lift?
28@docs lift3, lift4, lift5, lift6, lift7, lift8
28@docs lift3, lift4, lift5, lift6, lift7, lift8
29
29
libraries/String.elm+45−8
@@ -3,11 +3,10 @@ module String where
3are enclosed in `"double quotes"`. Strings are *not* lists of characters.
3are enclosed in `"double quotes"`. Strings are *not* lists of characters.
4
4
5# Basics
5# Basics
6−@docs isEmpty, length, cons, uncons, reverse,
6+@docs isEmpty, length, reverse, repeat
7− map, filter, foldl, foldr, any, all, repeat
8
7
9−# Split and Join
8+# Building and Splitting
10−@docs split, join, words, lines
9+@docs cons, uncons, append, concat, split, join, words, lines
11
10
12# Get Substrings
11# Get Substrings
13@docs sub, left, right, dropLeft, dropRight
12@docs sub, left, right, dropLeft, dropRight
@@ -15,8 +14,8 @@ are enclosed in `"double quotes"`. Strings are *not* lists of characters.
15# Check for Substrings
14# Check for Substrings
16@docs contains, startsWith, endsWith, indexes, indices
15@docs contains, startsWith, endsWith, indexes, indices
17
16
18−# Conversion To Numbers
17+# Conversions
19−@docs toInt, toFloat
18+@docs toInt, toFloat, toList, fromList
20
19
21# Formatting
20# Formatting
22Cosmetic operations such as padding with extra characters or trimming whitespace.
21Cosmetic operations such as padding with extra characters or trimming whitespace.
@@ -24,6 +23,9 @@ Cosmetic operations such as padding with extra characters or trimming whitespace
24@docs toUpper, toLower,
23@docs toUpper, toLower,
25 pad, padLeft, padRight,
24 pad, padLeft, padRight,
26 trim, trimLeft, trimRight
25 trim, trimLeft, trimRight
26+
27+# Higher-Order Functions
28+@docs map, filter, foldl, foldr, any, all
27-}
29-}
28
30
29import Native.String
31import Native.String
@@ -46,6 +48,21 @@ pattern match on strings exactly as you would with lists.
46uncons : String -> Maybe (Char, String)
48uncons : String -> Maybe (Char, String)
47uncons = Native.String.uncons
49uncons = Native.String.uncons
48
50
51+{-| Append two strings. You can also use [the `(++)` operator](/library/List.elm#++)
52+to do this.
53+
54+ append "butter" "fly" == "butterfly"
55+-}
56+append : String -> String -> String
57+append = Native.String.append
58+
59+{-| Concatenate many strings into one.
60+
61+ concat ["never","the","less"] == "nevertheless"
62+-}
63+concat : [String] -> String
64+concat = Native.String.concat
65+
49{-| Get the length of a string `(length "innumerable" == 11)` -}
66{-| Get the length of a string `(length "innumerable" == 11)` -}
50length : String -> Int
67length : String -> Int
51length = Native.String.length
68length = Native.String.length
@@ -68,12 +85,16 @@ filter = Native.String.filter
68reverse : String -> String
85reverse : String -> String
69reverse = Native.String.reverse
86reverse = Native.String.reverse
70
87
71−{-|
88+{-| Reduce a string from the left:
89+
90+ foldl cons "" "time" == "emit"
72-}
91-}
73foldl : (Char -> b -> b) -> b -> String -> b
92foldl : (Char -> b -> b) -> b -> String -> b
74foldl = Native.String.foldl
93foldl = Native.String.foldl
75
94
76−{-|
95+{-| Reduce a string from the right:
96+
97+ foldr cons "" "time" == "time"
77-}
98-}
78foldr : (Char -> b -> b) -> b -> String -> b
99foldr : (Char -> b -> b) -> b -> String -> b
79foldr = Native.String.foldr
100foldr = Native.String.foldr
@@ -272,3 +293,19 @@ toInt = Native.String.toInt
272-}
293-}
273toFloat : String -> Maybe Float
294toFloat : String -> Maybe Float
274toFloat = Native.String.toFloat
295toFloat = Native.String.toFloat
296+
297+{-| Convert a string to a list of characters.
298+
299+ toList "abc" == ['a','b','c']
300+-}
301+toList : String -> [Char]
302+toList = Native.String.toList
303+
304+{-| Convert a list of characters into a String. Can be useful if you
305+want to create a string primarly by consing, perhaps for decoding
306+something.
307+
308+ fromList ['a','b','c'] == "abc"
309+-}
310+fromList : String -> [Char]
311+fromList = Native.String.fromList
runtime/Render/Utils.js+2−2
@@ -39,8 +39,8 @@ return {addTo:addTo,
39 newElement:newElement,
39 newElement:newElement,
40 extract : extract,
40 extract : extract,
41 fromList: List.toArray,
41 fromList: List.toArray,
42− fromString: function(s) { return List.toArray(s).join(''); },
42+ fromString: function(s) { return s; },
43− toString: List.fromArray,
43+ toString: function(s) { return s; },
44 eq: Elm.Native.Utils.make({}).eq,
44 eq: Elm.Native.Utils.make({}).eq,
45 addTransform: addTransform,
45 addTransform: addTransform,
46 removeTransform: removeTransform
46 removeTransform: removeTransform
server/elm-server.cabal+2−2
@@ -1,5 +1,5 @@
1Name: elm-server
1Name: elm-server
2−Version: 0.9.0.2
2+Version: 0.10
3Synopsis: The Elm language server.
3Synopsis: The Elm language server.
4Description: This package provides a standalone, Happstack-based Elm server.
4Description: This package provides a standalone, Happstack-based Elm server.
5
5
@@ -36,5 +36,5 @@ Executable elm-server
36 happstack-server,
36 happstack-server,
37 deepseq,
37 deepseq,
38 filepath,
38 filepath,
39− Elm >= 0.9.0.2,
39+ Elm >= 0.10,
40 process
40 process