Merge branch 'master' into dev

This commit is contained in:
Evan Czaplicki 2013-10-28 11:27:07 +01:00
commit d8ced9ee74
22 changed files with 211 additions and 99 deletions

View file

@ -1,5 +1,5 @@
Name: Elm Name: Elm
Version: 0.9.0.2 Version: 0.10.0.2
Synopsis: The Elm language module. Synopsis: The Elm language module.
Description: Elm aims to make client-side web-development more pleasant. Description: Elm aims to make client-side web-development more pleasant.
It is a statically/strongly typed, functional reactive It is a statically/strongly typed, functional reactive
@ -88,7 +88,7 @@ Library
directory, directory,
filepath, filepath,
indents, indents,
language-ecmascript, language-ecmascript < 1,
mtl >= 2, mtl >= 2,
pandoc >= 1.10, pandoc >= 1.10,
parsec >= 3.1.1, parsec >= 3.1.1,
@ -157,7 +157,7 @@ Executable elm
directory, directory,
filepath, filepath,
indents, indents,
language-ecmascript, language-ecmascript < 1,
mtl >= 2, mtl >= 2,
pandoc >= 1.10, pandoc >= 1.10,
parsec >= 3.1.1, parsec >= 3.1.1,

View file

@ -3,8 +3,7 @@ Learn about the Elm programming language at [elm-lang.org](http://elm-lang.org/)
## Install ## Install
Download the [Haskell Platform 2012.2.0.0](http://hackage.haskell.org/platform/). Download the [Haskell Platform 2012.2.0.0 or later](http://hackage.haskell.org/platform/).
Elm definitely works with GHC 7.4, so newer versions of the Haskell Platform may work too.
Once the Haskell Platform is installed: Once the Haskell Platform is installed:
cabal update cabal update
@ -39,10 +38,10 @@ commands place a simple program into `Main.elm`. Do this manually if you do not
have `printf`. The final command starts the Elm server at [localhost:8000](http://localhost:8000/), have `printf`. The final command starts the Elm server at [localhost:8000](http://localhost:8000/),
allowing you to navigate to `Main.elm` and see your first program in action. allowing you to navigate to `Main.elm` and see your first program in action.
#### Wrap up #### Final Notes
The `elm` package provides support for compilation of Elm code directly in Haskell and QuasiQuoting. The `elm` package provides support for compilation of Elm code directly in Haskell.
Check it out on Hackage if you are interested. Check it out [on Hackage](http://hackage.haskell.org/package/Elm) if you are interested.
If you are stuck, email [the list](https://groups.google.com/forum/?fromgroups#!forum/elm-discuss) If you are stuck, email [the list](https://groups.google.com/forum/?fromgroups#!forum/elm-discuss)
or ask a question in the [#Elm IRC channel](http://webchat.freenode.net/?channels=elm). or ask a question in the [#Elm IRC channel](http://webchat.freenode.net/?channels=elm).

View file

@ -243,14 +243,17 @@ match :: (Show a) => a -> Case.Match () () -> State Int [Statement ()]
match span mtch = match span mtch =
case mtch of case mtch of
Case.Match name clauses mtch' -> Case.Match name clauses mtch' ->
do clauses' <- mapM (clause span name) clauses do (isChars, clauses') <- unzip <$> mapM (clause span name) clauses
mtch'' <- match span mtch' mtch'' <- match span mtch'
return (SwitchStmt () (access name) clauses' : mtch'') return (SwitchStmt () (format isChars (access name)) clauses' : mtch'')
where where
isLiteral p = case p of isLiteral p = case p of
Case.Clause (Right _) _ _ -> True Case.Clause (Right _) _ _ -> True
_ -> False _ -> False
access name = if any isLiteral clauses then ref name else dotSep [name,"ctor"] access name = if any isLiteral clauses then ref name else dotSep [name,"ctor"]
format isChars e
| or isChars = InfixExpr () OpAdd e (string "")
| otherwise = e
Case.Fail -> Case.Fail ->
return [ ExprStmt () (obj "_E.Case" `call` [ref "$moduleName", string (show span)]) ] return [ ExprStmt () (obj "_E.Case" `call` [ref "$moduleName", string (show span)]) ]
@ -268,10 +271,13 @@ match span mtch =
_ -> dropEnd (acc ++ [m]) ms _ -> dropEnd (acc ++ [m]) ms
clause span variable (Case.Clause value vars mtch) = clause span variable (Case.Clause value vars mtch) =
CaseClause () pattern <$> match span (Case.matchSubst (zip vars vars') mtch) (,) isChar . CaseClause () pattern <$> match span (Case.matchSubst (zip vars vars') mtch)
where where
vars' = map (\n -> variable ++ "._" ++ show n) [0..] vars' = map (\n -> variable ++ "._" ++ show n) [0..]
pattern = case value of (isChar, pattern) =
case value of
Right (Chr c) -> (True, string [c])
_ -> (,) False $ case value of
Right (Boolean b) -> BoolLit () b Right (Boolean b) -> BoolLit () b
Right lit -> literal lit Right lit -> literal lit
Left name -> string $ case List.elemIndices '.' name of Left name -> string $ case List.elemIndices '.' name of

View file

@ -25,16 +25,19 @@ tuple = do ts <- parens (commaSep expr)
record :: IParser T.Type record :: IParser T.Type
record = record =
do char '{' ; whitespace do char '{' ; whitespace
ext <- extend (ext,fs) <- extended <|> normal
fs <- fields
dumbWhitespace ; char '}' dumbWhitespace ; char '}'
return (T.Record fs ext) return (T.Record fs ext)
where where
extend = option T.EmptyRecord . try $ do normal = (,) T.EmptyRecord <$> commaSep fields
t <- tvar
whitespace >> string "|" >> whitespace -- extended record types require at least one field
return t extended = do
fields = commaSep1 $ do ext <- try (const <$> tvar <*> (whitespace >> string "|"))
whitespace
(,) ext <$> commaSep1 fields
fields = do
lbl <- rLabel lbl <- rLabel
whitespace >> hasType >> whitespace whitespace >> hasType >> whitespace
(,) lbl <$> expr (,) lbl <$> expr

View file

@ -4,6 +4,8 @@ module SourceSyntax.Declaration where
import Data.Data import Data.Data
import qualified SourceSyntax.Expression as Expr import qualified SourceSyntax.Expression as Expr
import SourceSyntax.Type import SourceSyntax.Type
import SourceSyntax.PrettyPrint
import Text.PrettyPrint as P
data Declaration tipe var data Declaration tipe var
= Definition (Expr.Def tipe var) = Definition (Expr.Def tipe var)
@ -23,3 +25,24 @@ instance Show Assoc where
L -> "left" L -> "left"
N -> "non" N -> "non"
R -> "right" R -> "right"
instance Pretty (Declaration t v) where
pretty decl =
case decl of
Definition def -> pretty def
Datatype tipe tvars ctors ->
P.hang (P.text "data" <+> P.text tipe <+> P.hsep (map P.text tvars)) 4
(P.sep $ zipWith join ("=" : repeat "|") ctors)
where
join c ctor = P.text c <+> prettyCtor ctor
prettyCtor (name, tipes) =
P.hang (P.text name) 2 (P.sep (map prettyParens tipes))
TypeAlias name tvars tipe ->
let alias = P.text name <+> P.hsep (map P.text tvars) in
P.hang (P.text "type" <+> alias <+> P.equals) 4 (pretty tipe)
-- TODO: actually write out the other cases. They are currently unused, but
-- this is probably going to be a bug someday.
_ -> P.text (show decl)

View file

@ -2,9 +2,11 @@ module Transform.Check (mistakes) where
import Transform.SortDefinitions (boundVars) import Transform.SortDefinitions (boundVars)
import SourceSyntax.Everything import SourceSyntax.Everything
import SourceSyntax.PrettyPrint
import qualified SourceSyntax.Type as T import qualified SourceSyntax.Type as T
import Data.List as List import Data.List as List
import qualified Data.Map as Map import qualified Data.Map as Map
import qualified Data.Maybe as Maybe
import qualified Data.Set as Set import qualified Data.Set as Set
import Data.Data import Data.Data
import Data.Generics.Uniplate.Data import Data.Generics.Uniplate.Data
@ -13,7 +15,7 @@ import Text.PrettyPrint as P
mistakes :: (Data t, Data v) => [Declaration t v] -> [Doc] mistakes :: (Data t, Data v) => [Declaration t v] -> [Doc]
mistakes decls = mistakes decls =
map P.text $ concatMap findErrors (getLets decls) illFormedTypes decls ++ map P.text (concatMap findErrors (getLets decls))
where where
findErrors defs = duplicates defs ++ badOrder defs findErrors defs = duplicates defs ++ badOrder defs
@ -60,4 +62,46 @@ badOrder defs = go defs
_ -> [] _ -> []
illFormedTypes :: [Declaration t v] -> [Doc]
illFormedTypes decls = map report (Maybe.mapMaybe isIllFormed (aliases ++ adts))
where
aliases = [ (decl, tvars, [tipe]) | decl@(TypeAlias _ tvars tipe) <- decls ]
adts = [ (decl, tvars, concatMap snd ctors) | decl@(Datatype _ tvars ctors) <- decls ]
freeVars tipe =
case tipe of
T.Lambda t1 t2 -> Set.union (freeVars t1) (freeVars t2)
T.Var x -> Set.singleton x
T.Data _ ts -> Set.unions (map freeVars ts)
T.EmptyRecord -> Set.empty
T.Record fields ext -> Set.unions (freeVars ext : map (freeVars . snd) fields)
undeclared tvars tipes = Set.difference used declared
where
used = Set.unions (map freeVars tipes)
declared = Set.fromList tvars
isIllFormed (decl, tvars, tipes) =
let unbound = undeclared tvars tipes in
if Set.null unbound then Nothing
else Just (decl, Set.toList unbound)
report (decl, tvars) =
P.vcat [ P.text $ "Error: type variable" ++ listing ++ " unbound in:"
, P.text "\n"
, nest 4 (pretty decl) ]
where
listing =
case tvars of
[tvar] -> " " ++ quote tvar ++ " is"
_ -> "s" ++ addCommas (map ((++) " ") (addAnd (map quote tvars))) ++ " are"
addCommas xs
| length xs < 3 = concat xs
| otherwise = intercalate "," xs
addAnd xs
| length xs < 2 = xs
| otherwise = zipWith (++) (replicate (length xs - 1) "" ++ ["and "]) xs
quote tvar = "'" ++ tvar ++ "'"

View file

@ -6,7 +6,7 @@ module Color where
built-in names. built-in names.
# Creation # Creation
@docs rgb, rgba, hsv, hsva, grayscale, greyscale @docs rgb, rgba, hsv, hsva, greyscale, grayscale
# From Other Colors # From Other Colors
@docs complement @docs complement

View file

@ -52,28 +52,16 @@ have the equivalence: `(partition es == (lefts es, rights es))`
partition : [Either a b] -> ([a],[b]) partition : [Either a b] -> ([a],[b])
partition es = List.foldr consEither ([],[]) es partition es = List.foldr consEither ([],[]) es
{-| If `Left`, add the value to the front of the list.
If `Right`, return the list unchanged
-}
consLeft : Either a b -> [a] -> [a]
consLeft e vs = consLeft e vs =
case e of case e of
Left v -> v::vs Left v -> v::vs
Right _ -> vs Right _ -> vs
{-| If `Right`, add the value to the front of the list.
If `Left`, return the list unchanged.
-}
consRight : Either a b -> [b] -> [b]
consRight e vs = consRight e vs =
case e of case e of
Left _ -> vs Left _ -> vs
Right v -> v::vs Right v -> v::vs
{-| If `Left`, add the value to the left list.
If `Right`, add the value to the right list.
-}
consEither : Either a b -> ([a], [b]) -> ([a], [b])
consEither e (ls,rs) = consEither e (ls,rs) =
case e of case e of
Left l -> (l::ls,rs) Left l -> (l::ls,rs)

View file

@ -125,7 +125,7 @@ tiled to fill the entire shape.
textured : String -> Shape -> Form textured : String -> Shape -> Form
textured src shape = fill (Texture src) shape textured src shape = fill (Texture src) shape
{-| Fill a shape with a [gradient](/docs/Color.elm#linear). -} {-| Fill a shape with a [gradient](/library/Color.elm#linear). -}
gradient : Gradient -> Shape -> Form gradient : Gradient -> Shape -> Form
gradient grad shape = fill (Grad grad) shape gradient grad shape = fill (Grad grad) shape
@ -204,37 +204,37 @@ collage : Int -> Int -> [Form] -> Element
collage = Native.Graphics.Collage.collage collage = Native.Graphics.Collage.collage
type Path = [(number,number)] type Path = [(Float,Float)]
{-| Create a path that follows a sequence of points. -} {-| Create a path that follows a sequence of points. -}
path : [(number,number)] -> Path path : [(Float,Float)] -> Path
path ps = ps path ps = ps
{-| Create a path along a given line segment. -} {-| Create a path along a given line segment. -}
segment : (number,number) -> (number,number) -> Path segment : (Float,Float) -> (Float,Float) -> Path
segment p1 p2 = [p1,p2] segment p1 p2 = [p1,p2]
type Shape = [(number,number)] type Shape = [(Float,Float)]
{-| Create an arbitrary polygon by specifying its corners in order. {-| Create an arbitrary polygon by specifying its corners in order.
`polygon` will automatically close all shapes, so the given list `polygon` will automatically close all shapes, so the given list
of points does not need to start and end with the same position. of points does not need to start and end with the same position.
-} -}
polygon : [(number,number)] -> Shape polygon : [(Float,Float)] -> Shape
polygon points = points polygon points = points
{-| A rectangle with a given width and height. -} {-| A rectangle with a given width and height. -}
rect : number -> number -> Shape rect : Float -> Float -> Shape
rect w h = let hw = w/2 rect w h = let hw = w/2
hh = h/2 hh = h/2
in [ (0-hw,0-hh), (0-hw,hh), (hw,hh), (hw,0-hh) ] in [ (0-hw,0-hh), (0-hw,hh), (hw,hh), (hw,0-hh) ]
{-| A square with a given edge length. -} {-| A square with a given edge length. -}
square : number -> Shape square : Float -> Shape
square n = rect n n square n = rect n n
{-| An oval with a given width and height. -} {-| An oval with a given width and height. -}
oval : number -> number -> Shape oval : Float -> Float -> Shape
oval w h = oval w h =
let n = 50 let n = 50
t = 2 * pi / n t = 2 * pi / n
@ -244,7 +244,7 @@ oval w h =
in List.map f [0..n-1] in List.map f [0..n-1]
{-| A circle with a given radius. -} {-| A circle with a given radius. -}
circle : number -> Shape circle : Float -> Shape
circle r = oval (2*r) (2*r) circle r = oval (2*r) (2*r)
{-| A regular polygon with N sides. The first argument specifies the number {-| 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
ngon 5 30 ngon 5 30
-} -}
ngon : Int -> number -> Shape ngon : Int -> Float -> Shape
ngon n r = ngon n r =
let m = toFloat n let m = toFloat n
t = 2 * pi / m t = 2 * pi / m

View file

@ -204,9 +204,8 @@ flow dir es =
DIn -> newFlow (List.maximum ws) (List.maximum hs) DIn -> newFlow (List.maximum ws) (List.maximum hs)
DOut -> newFlow (List.maximum ws) (List.maximum hs) DOut -> newFlow (List.maximum ws) (List.maximum hs)
{-| Stack elements vertically. To put `a` above `b` you would say: {-| Stack elements vertically.
To put `a` above `b` you would say: ``a `above` b``
a `above` b
-} -}
above : Element -> Element -> Element above : Element -> Element -> Element
above hi lo = above hi lo =
@ -214,9 +213,8 @@ above hi lo =
(heightOf hi + heightOf lo) (heightOf hi + heightOf lo)
(Flow DDown [hi,lo]) (Flow DDown [hi,lo])
{-| Stack elements vertically. To put `a` below `b` you would say: {-| Stack elements vertically.
To put `a` below `b` you would say: ``a `below` b``
a `below` b
-} -}
below : Element -> Element -> Element below : Element -> Element -> Element
below lo hi = below lo hi =
@ -225,6 +223,7 @@ below lo hi =
(Flow DDown [hi,lo]) (Flow DDown [hi,lo])
{-| Put elements beside each other horizontally. {-| Put elements beside each other horizontally.
To put `a` beside `b` you would say: ``a `beside` b``
-} -}
beside : Element -> Element -> Element beside : Element -> Element -> Element
beside lft rht = beside lft rht =
@ -232,8 +231,8 @@ beside lft rht =
(max (heightOf lft) (heightOf rht)) (max (heightOf lft) (heightOf rht))
(Flow right [lft,rht]) (Flow right [lft,rht])
{-| Layer elements on top of each other, starting from the bottom. {-| Layer elements on top of each other, starting from the bottom:
`(layers == flow outward)` `layers == flow outward`
-} -}
layers : [Element] -> Element layers : [Element] -> Element
layers es = layers es =

View file

@ -9,7 +9,7 @@ integration.
@docs toString, toInt, toFloat, toBool, toList @docs toString, toInt, toFloat, toBool, toList
# JavaScript from Elm # JavaScript from Elm
@docs fromString, fromInt, fromFloat, fromBool fromList @docs fromString, fromInt, fromFloat, fromBool, fromList
-} -}
{- {-
# DOM Nodes and Elements # DOM Nodes and Elements

View file

@ -39,11 +39,6 @@ isJust = maybe False (\_ -> True)
isNothing : Maybe a -> Bool isNothing : Maybe a -> Bool
isNothing = not . isJust isNothing = not . isJust
{-| If `Just`, adds the value to the front of the list.
If `Nothing`, list is unchanged.
-}
cons : Maybe a -> [a] -> [a]
cons mx xs = maybe xs (\x -> x :: xs) mx cons mx xs = maybe xs (\x -> x :: xs) mx
{-| Filters out Nothings and extracts the remaining values. {-| Filters out Nothings and extracts the remaining values.

View file

@ -33,7 +33,7 @@ Elm.Native.Basics.make = function(elm) {
mod:mod, mod:mod,
pi:Math.PI, pi:Math.PI,
e:Math.e, e:Math.E,
cos:Math.cos, cos:Math.cos,
sin:Math.sin, sin:Math.sin,
tan:Math.tan, tan:Math.tan,

View file

@ -21,7 +21,7 @@ Elm.Native.Show.make = function(elm) {
return v ? "True" : "False"; return v ? "True" : "False";
} else if (type === "number") { } else if (type === "number") {
return v+""; return v+"";
} else if (v.isChar && v instanceof String) { } else if ((v instanceof String) && v.isChar) {
return "'" + addSlashes(v) + "'"; return "'" + addSlashes(v) + "'";
} else if (type === "string") { } else if (type === "string") {
return '"' + addSlashes(v) + '"'; return '"' + addSlashes(v) + '"';

View file

@ -26,10 +26,6 @@ Elm.Native.Http.make = function(elm) {
} }
} }
function setHeader(pair) {
request.setRequestHeader( JS.fromString(pair._0), JS.fromString(pair._1) );
}
function sendReq(queue,responses,req) { function sendReq(queue,responses,req) {
var response = { value: { ctor:'Waiting' } }; var response = { value: { ctor:'Waiting' } };
queue.push(response); queue.push(response);
@ -46,6 +42,9 @@ Elm.Native.Http.make = function(elm) {
} }
}; };
request.open(JS.fromString(req.verb), JS.fromString(req.url), true); request.open(JS.fromString(req.verb), JS.fromString(req.url), true);
function setHeader(pair) {
request.setRequestHeader( JS.fromString(pair._0), JS.fromString(pair._1) );
}
List.map(setHeader)(req.headers); List.map(setHeader)(req.headers);
request.send(JS.fromString(req.body)); request.send(JS.fromString(req.body));
} }

View file

@ -22,14 +22,24 @@ Elm.Native.String.make = function(elm) {
return (hd = str[0]) ? Maybe.Just(Utils.Tuple2(Utils.chr(hd), str.slice(1))) return (hd = str[0]) ? Maybe.Just(Utils.Tuple2(Utils.chr(hd), str.slice(1)))
: Maybe.Nothing; : Maybe.Nothing;
} }
function append(a,b) {
return a + b;
}
function concat(strs) {
return JS.fromList(strs).join('');
}
function length(str) { function length(str) {
return str.length; return str.length;
} }
function map(f,str) { function map(f,str) {
return str.split('').map(f).join(''); var out = str.split('');
for (var i = out.length; i--; ) {
out[i] = f(Utils.chr(out[i]));
}
return out.join('');
} }
function filter(pred,str) { function filter(pred,str) {
return str.split('').filter(pred).join(''); return str.split('').map(Utils.chr).filter(pred).join('');
} }
function reverse(str) { function reverse(str) {
return str.split('').reverse().join(''); return str.split('').reverse().join('');
@ -37,13 +47,13 @@ Elm.Native.String.make = function(elm) {
function foldl(f,b,str) { function foldl(f,b,str) {
var len = str.length; var len = str.length;
for (var i = 0; i < len; ++i) { for (var i = 0; i < len; ++i) {
b = A2(f, str[i], b); b = A2(f, Utils.chr(str[i]), b);
} }
return b; return b;
} }
function foldr(f,b,str) { function foldr(f,b,str) {
for (var i = str.length; i--; ) { for (var i = str.length; i--; ) {
b = A2(f, str[i], b); b = A2(f, Utils.chr(str[i]), b);
} }
return b; return b;
} }
@ -116,13 +126,13 @@ Elm.Native.String.make = function(elm) {
function any(pred, str) { function any(pred, str) {
for (var i = str.length; i--; ) { for (var i = str.length; i--; ) {
if (pred(str[i])) return true; if (pred(Utils.chr(str[i]))) return true;
} }
return false; return false;
} }
function all(pred, str) { function all(pred, str) {
for (var i = str.length; i--; ) { for (var i = str.length; i--; ) {
if (!pred(str[i])) return false; if (!pred(Utils.chr(str[i]))) return false;
} }
return true; return true;
} }
@ -147,8 +157,7 @@ Elm.Native.String.make = function(elm) {
return JS.toList(is); return JS.toList(is);
} }
function toInt(str) { function toInt(s) {
var s = JS.fromString(str);
var len = s.length; var len = s.length;
if (len === 0) { return Maybe.Nothing; } if (len === 0) { return Maybe.Nothing; }
var start = 0; var start = 0;
@ -162,8 +171,7 @@ Elm.Native.String.make = function(elm) {
return Maybe.Just(parseInt(s, 10)); return Maybe.Just(parseInt(s, 10));
} }
function toFloat(str) { function toFloat(s) {
var s = JS.fromString(str);
var len = s.length; var len = s.length;
if (len === 0) { return Maybe.Nothing; } if (len === 0) { return Maybe.Nothing; }
var start = 0; var start = 0;
@ -183,10 +191,19 @@ Elm.Native.String.make = function(elm) {
return Maybe.Just(parseFloat(s)); return Maybe.Just(parseFloat(s));
} }
function toList(str) {
return JS.toList(str.split('').map(Utils.chr));
}
function fromList(chars) {
return JS.fromList(chars).join('');
}
return Elm.Native.String.values = { return Elm.Native.String.values = {
isEmpty: isEmpty, isEmpty: isEmpty,
cons: F2(cons), cons: F2(cons),
uncons: uncons, uncons: uncons,
append: F2(append),
concat: concat,
length: length, length: length,
map: F2(map), map: F2(map),
filter: F2(filter), filter: F2(filter),
@ -228,5 +245,7 @@ Elm.Native.String.make = function(elm) {
toInt: toInt, toInt: toInt,
toFloat: toFloat, toFloat: toFloat,
toList: toList,
fromList: fromList,
}; };
}; };

View file

@ -3,7 +3,7 @@ module Random where
{-| Since the core of Elm is pure, randomness must be handled via signals. {-| Since the core of Elm is pure, randomness must be handled via signals.
# Random Numbers # Random Numbers
@docs range, float @docs range, float, floatList
-} -}
import Signal (Signal) import Signal (Signal)

View file

@ -15,15 +15,15 @@ the [`Time`](/docs/Signal/Time.elm) library.
# Combine # Combine
@docs constant, lift, lift2, merge, merges, combine @docs constant, lift, lift2, merge, merges, combine
# Pretty Lift
@docs (<~), (~)
# Past-Dependence # Past-Dependence
@docs foldp, count, countIf @docs foldp, count, countIf
#Filters #Filters
@docs keepIf, dropIf, keepWhen, dropWhen, dropRepeats, sampleOn @docs keepIf, dropIf, keepWhen, dropWhen, dropRepeats, sampleOn
# Pretty Lift
@docs (<~), (~)
# Do you even lift? # Do you even lift?
@docs lift3, lift4, lift5, lift6, lift7, lift8 @docs lift3, lift4, lift5, lift6, lift7, lift8

View file

@ -3,11 +3,10 @@ module String where
are enclosed in `"double quotes"`. Strings are *not* lists of characters. are enclosed in `"double quotes"`. Strings are *not* lists of characters.
# Basics # Basics
@docs isEmpty, length, cons, uncons, reverse, @docs isEmpty, length, reverse, repeat
map, filter, foldl, foldr, any, all, repeat
# Split and Join # Building and Splitting
@docs split, join, words, lines @docs cons, uncons, append, concat, split, join, words, lines
# Get Substrings # Get Substrings
@docs sub, left, right, dropLeft, dropRight @docs sub, left, right, dropLeft, dropRight
@ -15,8 +14,8 @@ are enclosed in `"double quotes"`. Strings are *not* lists of characters.
# Check for Substrings # Check for Substrings
@docs contains, startsWith, endsWith, indexes, indices @docs contains, startsWith, endsWith, indexes, indices
# Conversion To Numbers # Conversions
@docs toInt, toFloat @docs toInt, toFloat, toList, fromList
# Formatting # Formatting
Cosmetic operations such as padding with extra characters or trimming whitespace. Cosmetic 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
@docs toUpper, toLower, @docs toUpper, toLower,
pad, padLeft, padRight, pad, padLeft, padRight,
trim, trimLeft, trimRight trim, trimLeft, trimRight
# Higher-Order Functions
@docs map, filter, foldl, foldr, any, all
-} -}
import Native.String import Native.String
@ -46,6 +48,21 @@ pattern match on strings exactly as you would with lists.
uncons : String -> Maybe (Char, String) uncons : String -> Maybe (Char, String)
uncons = Native.String.uncons uncons = Native.String.uncons
{-| Append two strings. You can also use [the `(++)` operator](/library/List.elm#++)
to do this.
append "butter" "fly" == "butterfly"
-}
append : String -> String -> String
append = Native.String.append
{-| Concatenate many strings into one.
concat ["never","the","less"] == "nevertheless"
-}
concat : [String] -> String
concat = Native.String.concat
{-| Get the length of a string `(length "innumerable" == 11)` -} {-| Get the length of a string `(length "innumerable" == 11)` -}
length : String -> Int length : String -> Int
length = Native.String.length length = Native.String.length
@ -68,12 +85,16 @@ filter = Native.String.filter
reverse : String -> String reverse : String -> String
reverse = Native.String.reverse reverse = Native.String.reverse
{-| {-| Reduce a string from the left:
foldl cons "" "time" == "emit"
-} -}
foldl : (Char -> b -> b) -> b -> String -> b foldl : (Char -> b -> b) -> b -> String -> b
foldl = Native.String.foldl foldl = Native.String.foldl
{-| {-| Reduce a string from the right:
foldr cons "" "time" == "time"
-} -}
foldr : (Char -> b -> b) -> b -> String -> b foldr : (Char -> b -> b) -> b -> String -> b
foldr = Native.String.foldr foldr = Native.String.foldr
@ -272,3 +293,19 @@ toInt = Native.String.toInt
-} -}
toFloat : String -> Maybe Float toFloat : String -> Maybe Float
toFloat = Native.String.toFloat toFloat = Native.String.toFloat
{-| Convert a string to a list of characters.
toList "abc" == ['a','b','c']
-}
toList : String -> [Char]
toList = Native.String.toList
{-| Convert a list of characters into a String. Can be useful if you
want to create a string primarly by consing, perhaps for decoding
something.
fromList ['a','b','c'] == "abc"
-}
fromList : String -> [Char]
fromList = Native.String.fromList

View file

@ -39,8 +39,8 @@ return {addTo:addTo,
newElement:newElement, newElement:newElement,
extract : extract, extract : extract,
fromList: List.toArray, fromList: List.toArray,
fromString: function(s) { return List.toArray(s).join(''); }, fromString: function(s) { return s; },
toString: List.fromArray, toString: function(s) { return s; },
eq: Elm.Native.Utils.make({}).eq, eq: Elm.Native.Utils.make({}).eq,
addTransform: addTransform, addTransform: addTransform,
removeTransform: removeTransform removeTransform: removeTransform

View file

@ -1,5 +1,5 @@
Name: elm-server Name: elm-server
Version: 0.9.0.2 Version: 0.10
Synopsis: The Elm language server. Synopsis: The Elm language server.
Description: This package provides a standalone, Happstack-based Elm server. Description: This package provides a standalone, Happstack-based Elm server.
@ -36,5 +36,5 @@ Executable elm-server
happstack-server, happstack-server,
deepseq, deepseq,
filepath, filepath,
Elm >= 0.9.0.2, Elm >= 0.10,
process process