Merge branch 'master' into dev
This commit is contained in:
commit
d8ced9ee74
22 changed files with 211 additions and 99 deletions
|
@ -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,
|
||||||
|
|
|
@ -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).
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
|
@ -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 ++ "'"
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 =
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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) + '"';
|
||||||
|
|
|
@ -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));
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
};
|
};
|
||||||
};
|
};
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue