on master help sign in
Merge pull request #595 from maxsnew/list-funs
8928784Evan Czaplicki
libraries/List.elm+17−14
@@ -171,11 +171,11 @@ not.
171 partition isEven [0..5] == ([0,2,4], [1,3,5])
171 partition isEven [0..5] == ([0,2,4], [1,3,5])
172-}
172-}
173partition : (a -> Bool) -> [a] -> ([a],[a])
173partition : (a -> Bool) -> [a] -> ([a],[a])
174−partition pred lst =
174+partition pred =
175− case lst of
175+ let step x (ts, fs) = if pred x
176− [] -> ([],[])
176+ then (x::ts, fs)
177− x::xs -> let (bs,cs) = partition pred xs in
177+ else (ts, x::fs)
178− if pred x then (x::bs,cs) else (bs,x::cs)
178+ in foldr step ([],[])
179
179
180{-| Combine two lists, combining them into tuples pairwise.
180{-| Combine two lists, combining them into tuples pairwise.
181If one list is longer, the extra elements are dropped.
181If one list is longer, the extra elements are dropped.
@@ -194,12 +194,13 @@ If one list is longer, the extra elements are dropped.
194zipWith : (a -> b -> c) -> [a] -> [b] -> [c]
194zipWith : (a -> b -> c) -> [a] -> [b] -> [c]
195zipWith = Native.List.zipWith
195zipWith = Native.List.zipWith
196
196
197−{-| Decompose a list of tuples. -}
197+{-| Decompose a list of tuples.
198+ unzip [(0, True), (17, False), (1337, True)] == ([0,17,1337], [True,False,True])
199+-}
198unzip : [(a,b)] -> ([a],[b])
200unzip : [(a,b)] -> ([a],[b])
199−unzip pairs =
201+unzip =
200− case pairs of
202+ let step (x,y) (xs, ys) = (x::xs, y::ys)
201− [] -> ([],[])
203+ in foldr step ([], [])
202− (x,y)::ps -> let (xs,ys) = (unzip ps) in (x::xs,y::ys)
203
204
204{-| Places the given value between all of the lists in the second
205{-| Places the given value between all of the lists in the second
205argument and concatenates the result.
206argument and concatenates the result.
@@ -215,10 +216,12 @@ join = Native.List.join
215-}
216-}
216intersperse : a -> [a] -> [a]
217intersperse : a -> [a] -> [a]
217intersperse sep xs =
218intersperse sep xs =
218− case xs of
219+ case xs of
219− a::b::cs -> a :: sep :: intersperse sep (b::cs)
220+ [] -> []
220− [a] -> [a]
221+ hd::tl ->
221− [] -> []
222+ let step x rest = sep :: x :: rest
223+ spersed = foldr step [] tl
224+ in hd :: spersed
222
225
223{-| Take the first n members of a list: `(take 2 [1,2,3,4] == [1,2])` -}
226{-| Take the first n members of a list: `(take 2 [1,2,3,4] == [1,2])` -}
224take : Int -> [a] -> [a]
227take : Int -> [a] -> [a]
libraries/Native/Utils.js+21−14
@@ -5,23 +5,30 @@ Elm.Native.Utils.make = function(elm) {
5 elm.Native.Utils = elm.Native.Utils || {};
5 elm.Native.Utils = elm.Native.Utils || {};
6 if (elm.Native.Utils.values) return elm.Native.Utils.values;
6 if (elm.Native.Utils.values) return elm.Native.Utils.values;
7
7
8− function eq(x,y) {
8+ function eq(l,r) {
9− if (x === y) return true;
9+ var stack = [{'x': l, 'y': r}]
10+ while (stack.length > 0) {
11+ var front = stack.pop();
12+ var x = front.x;
13+ var y = front.y;
14+ if (x === y) continue;
10− if (typeof x === "object") {
15+ if (typeof x === "object") {
11− var c = 0;
16+ var c = 0;
12− for (var i in x) {
17+ for (var i in x) {
13− ++c;
18+ ++c;
14− if (!eq(x[i],y[i])) {
19+ stack.push({ 'x': x[i], 'y': y[i] });
15− return false;
16 }
20 }
21+ if (c !== Object.keys(y).length) {
22+ return false;
23+ };
24+ } else if (typeof x === 'function') {
25+ throw new Error('Equality error: general function equality is ' +
26+ 'undecidable, and therefore, unsupported');
27+ } else {
28+ return false;
17 }
29 }
18− return c === Object.keys(y).length;
19− }
20− if (typeof x === 'function') {
21− throw new Error('Equality error: general function equality is ' +
22− 'undecidable, and therefore, unsupported');
23 }
30 }
24− return x === y;
31+ return true;
25 }
32 }
26
33
27 // code in Generate/JavaScript.hs depends on the particular
34 // code in Generate/JavaScript.hs depends on the particular
tests/elm/Test.elm+6−4
@@ -9,13 +9,15 @@ import IO.IO (..)
9import IO.Runner (Request, Response)
9import IO.Runner (Request, Response)
10import IO.Runner as Run
10import IO.Runner as Run
11
11
12−import Test.String as String
13−import Test.Trampoline as Trampoline
14import Test.Array as Array
12import Test.Array as Array
15import Test.Dict as Dict
13import Test.Dict as Dict
16−
14+import Test.List as List
15+import Test.Set as Set
16+import Test.String as String
17+import Test.Trampoline as Trampoline
18+
17tests : [Test]
19tests : [Test]
18−tests = String.tests ++ Trampoline.tests ++ Array.tests ++ Dict.tests
20+tests = String.tests ++ Trampoline.tests ++ Array.tests ++ Dict.tests ++ Set.tests ++ List.tests
19
21
20console : IO ()
22console : IO ()
21console = runDisplay tests
23console = runDisplay tests
tests/elm/Test/List.elmnew file+38
@@ -0,0 +1,38 @@
1+module Test.List (tests) where
2+
3+import List
4+
5+import ElmTest.Assertion (..)
6+import ElmTest.Test (..)
7+
8+tests : [Test]
9+tests =
10+ let partitionTests =
11+ let p1 = id
12+ p2 x = x < 3
13+ isEven n = n `mod` 2 == 0
14+ in [ test "simple partition" <| assertEqual ([True],[False]) (List.partition p1 [False, True]),
15+ test "order check" <| assertEqual ([2,1], [5,6]) (List.partition p2 [2,5,6,1]),
16+ test "partition doc check 1" <| assertEqual ([0,1,2], [3,4,5]) (partition p2 [0..5]),
17+ test "partition doc check 2" <| assertEqual ([0,2,4], [1,3,5]) (partition isEven [0..5]),
18+ let n = 100000
19+ ts = repeat n True
20+ fs = repeat n False
21+ in test "partition stress test" <| assertEqual (ts, fs) (partition p1 (fs++ts))
22+ ]
23+ unzipTests = [
24+ test "unzip doc check" <| assertEqual ([0,17,1337],[True,False,True]) (unzip [(0, True), (17, False), (1337, True)]),
25+ let n = 100000
26+ ts = repeat n True
27+ fs = repeat n False
28+ in test "unzip stress test" <| assertEqual (ts, fs) (unzip (zip ts fs))
29+ ]
30+ intersperseTests = [
31+ test "intersperse doc check" <| assertEqual ["turtles","on","turtles","on","turtles"] (intersperse "on" ["turtles","turtles","turtles"]),
32+ let n = 100000
33+ ts = repeat n True
34+ fs = repeat n False
35+ in test "intersperse stress test" <| assertEqual (tail . List.concat <| zipWith (\x y -> [x,y]) fs ts)
36+ (intersperse False ts)
37+ ]
38+ in List.concat [partitionTests, unzipTests, intersperseTests]
tests/elm/Test/Set.elm+6−5
@@ -1,18 +1,19 @@
1module Test.Set (tests) where
1module Test.Set (tests) where
2
2
3import Set
3import Set
4+import Set (Set)
4import List
5import List
5
6
6import ElmTest.Assertion (..)
7import ElmTest.Assertion (..)
7import ElmTest.Test (..)
8import ElmTest.Test (..)
8
9
9−set : Set
10+set : Set Int
10set = Set.fromList [1..100]
11set = Set.fromList [1..100]
11
12
12−setPart1 : Set
13+setPart1 : Set Int
13setPart1 = Set.fromList [1..50]
14setPart1 = Set.fromList [1..50]
14
15
15−setPart2 : Set
16+setPart2 : Set Int
16setPart2 = Set.fromList [51..100]
17setPart2 = Set.fromList [51..100]
17
18
18pred : Int -> Bool
19pred : Int -> Bool
@@ -21,6 +22,6 @@ pred x = x <= 50
21tests : [Test]
22tests : [Test]
22tests =
23tests =
23 let
24 let
24− filterTests = [assertEqual setPart1 <| filter pred set]
25+ filterTests = [test "Simple filter" <| assertEqual setPart1 <| Set.filter pred set]
25− partitionTests = [assertEqual (setPart1, setPart2) <| partition pred set]
26+ partitionTests = [test "Simple partition" <| assertEqual (setPart1, setPart2) <| Set.partition pred set]
26 in List.concat [partitionTests, filterTests]
27 in List.concat [partitionTests, filterTests]
tests/hs/LibTest.hs+5−2
@@ -1,5 +1,7 @@
1module Main where
1module Main where
2
2
3+import Control.Monad (unless)
4+import Data.List (isInfixOf)
3import System.Directory
5import System.Directory
4import System.Exit
6import System.Exit
5import System.FilePath
7import System.FilePath
@@ -11,8 +13,9 @@ main :: IO ()
11main = do
13main = do
12 top <- getCurrentDirectory
14 top <- getCurrentDirectory
13 let ioScript s = top</>"IO"</>s
15 let ioScript s = top</>"IO"</>s
14− runCmd "git submodule init"
16+ runCmd "git submodule update --init"
17+ out <- readProcess "npm" ["ls", "--parseable"] ""
15− runCmd "npm install jsdom"
18+ unless ("jsdom" `isInfixOf` out) $ runCmd "npm install jsdom"
16 setCurrentDirectory $ top</>"tests"</>"elm"
19 setCurrentDirectory $ top</>"tests"</>"elm"
17 runCmd $ concat [top</>"dist"</>"build"</>"elm"</>"elm --make --only-js --src-dir=" , top</>"automaton", " --src-dir=", top</>"IO", " --src-dir=", top</>"Elm-Test", " Test.elm"]
20 runCmd $ concat [top</>"dist"</>"build"</>"elm"</>"elm --make --only-js --src-dir=" , top</>"automaton", " --src-dir=", top</>"IO", " --src-dir=", top</>"Elm-Test", " Test.elm"]
18 runCmd $ unwords ["cat ", ioScript "prescript.js", Elm.runtime, "build"</>"Test.js", ioScript "handler.js", "> exe.js"]
21 runCmd $ unwords ["cat ", ioScript "prescript.js", Elm.runtime, "build"</>"Test.js", ioScript "handler.js", "> exe.js"]