From 95e7e77fbb6db12b7fc603ae83ed611755169e53 Mon Sep 17 00:00:00 2001 From: Daniel Wehner Date: Tue, 21 Mar 2017 08:48:18 +0100 Subject: [PATCH 1/6] Implement all the dict extra functions --- src/DictList.elm | 81 +++++++++++++++++++++++++++++ tests/src/DictExtraTests.elm | 98 ++++++++++++++++++++++++++++++++++++ tests/src/Main.elm | 2 + 3 files changed, 181 insertions(+) create mode 100644 tests/src/DictExtraTests.elm diff --git a/src/DictList.elm b/src/DictList.elm index 9957925..f69d463 100644 --- a/src/DictList.elm +++ b/src/DictList.elm @@ -61,6 +61,13 @@ module DictList -- Conversion , toDict , fromDict + -- dict extra + , groupBy + , fromListBy + , removeWhen + , removeMany + , keepOnly + , mapKeys ) {-| Have you ever wanted a `Dict`, but you need to maintain an arbitrary @@ -115,12 +122,15 @@ between an association list and a `DictList` via `toList` and `fromList`. # JSON @docs decodeObject, decodeArray, decodeWithKeys, decodeKeysAndValues + +@docs groupBy, fromListBy, removeWhen, removeMany, keepOnly, mapKeys -} import Dict exposing (Dict) import DictList.Compat exposing (customDecoder, decodeAndThen, first, maybeAndThen, second) import Json.Decode exposing (Decoder, keyValuePairs, value, decodeValue) import List.Extra +import Set {-| A `Dict` that maintains an arbitrary ordering of keys (rather than sorting @@ -937,6 +947,77 @@ fromDict dict = DictList dict (Dict.keys dict) +{-| Takes a key-fn and a list. +Creates a `Dict` which maps the key to a list of matching elements. + mary = {id=1, name="Mary"} + jack = {id=2, name="Jack"} + jill = {id=1, name="Jill"} + groupBy .id [mary, jack, jill] == Dict.fromList [(1, [mary, jill]), (2, [jack])] +-} +groupBy : (comparable1 -> a -> comparable2) -> DictList comparable1 a -> DictList comparable2 (List a) +groupBy keyfn list = + foldr + (\key x acc -> + update (keyfn key x) (Maybe.map ((::) x) >> Maybe.withDefault [ x ] >> Just) acc + ) + empty + list + + +{-| Create a dictionary from a list of values, by passing a function that can get a key from any such value. +If the function does not return unique keys, earlier values are discarded. +This can, for instance, be useful when constructing Dicts from a List of records with `id` fields: + mary = {id=1, name="Mary"} + jack = {id=2, name="Jack"} + jill = {id=1, name="Jill"} + fromListBy .id [mary, jack, jill] == Dict.fromList [(1, jack), (2, jill)] +-} +fromListBy : (comparable1 -> a -> comparable2) -> DictList comparable1 a -> DictList comparable2 a +fromListBy keyfn xs = + foldl + (\key x acc -> insert (keyfn key x) x acc) + empty + xs + + +{-| Remove elements which satisfies the predicate. + removeWhen (\_ v -> v == 1) (Dict.fromList [("Mary", 1), ("Jack", 2), ("Jill", 1)]) == Dict.fromList [("Jack", 2)] +-} +removeWhen : (comparable -> v -> Bool) -> DictList comparable v -> DictList comparable v +removeWhen pred dict = + filter (\k v -> not (pred k v)) dict + + +{-| Remove a key-value pair if its key appears in the set. +-} +removeMany : Set.Set comparable -> DictList comparable v -> DictList comparable v +removeMany set dict = + Set.foldl (\k acc -> remove k acc) dict set + + +{-| Keep a key-value pair if its key appears in the set. +-} +keepOnly : Set.Set comparable -> DictList comparable v -> DictList comparable v +keepOnly set dict = + Set.foldl + (\k acc -> + Maybe.withDefault acc <| Maybe.map (\v -> insert k v acc) (get k dict) + ) + empty + set + + +{-| Apply a function to all keys in a dictionary +-} +mapKeys : (comparable1 -> comparable2) -> DictList comparable1 v -> DictList comparable2 v +mapKeys keyMapper dict = + let + addKey key value d = + insert (keyMapper key) value d + in + foldl addKey empty dict + + ----------- -- Internal diff --git a/tests/src/DictExtraTests.elm b/tests/src/DictExtraTests.elm new file mode 100644 index 0000000..96cb334 --- /dev/null +++ b/tests/src/DictExtraTests.elm @@ -0,0 +1,98 @@ +module DictExtraTests exposing (tests) + +import Fuzz exposing (Fuzzer) +import DictList exposing (..) +import Expect +import Test exposing (..) +import Set + + +{-| Fuzz a DictList, given a fuzzer for the keys and values. +-} +fuzzDictList : Fuzzer comparable -> Fuzzer value -> Fuzzer (DictList comparable value) +fuzzDictList fuzzKey fuzzValue = + Fuzz.tuple ( fuzzKey, fuzzValue ) + |> Fuzz.list + |> Fuzz.map DictList.fromList + + +fuzzIntDictList : Fuzzer (DictList Int Int) +fuzzIntDictList = + fuzzDictList Fuzz.int Fuzz.int + + +threeElementList = + (fromList [ ( 1, 1 ), ( 2, 2 ), ( 3, 3 ) ]) + + +tests = + describe "List Tests" + [ dictExtraUnitTests + , dictExtraFuzzTests + ] + + +dictExtraUnitTests : Test +dictExtraUnitTests = + describe "Dict Extra Unittests" + [ describe "groupBy" + [ test "empty" <| \() -> Expect.equal (groupBy (\k v -> k) empty) empty + , test "always equal elements" <| \() -> Expect.equal (groupBy (\k v -> 1) (fromList [ ( 1, 1 ), ( 2, 2 ), ( 3, 3 ) ])) (fromList [ ( 1, [ 1, 2, 3 ] ) ]) + , test "map to original key" <| \() -> Expect.equal (groupBy (\k v -> k) (fromList [ ( 1, 1 ), ( 2, 2 ), ( 3, 3 ) ])) (fromList [ ( 3, [ 3 ] ), ( 2, [ 2 ] ), ( 1, [ 1 ] ) ]) + , test "odd-even" <| \() -> Expect.equal (groupBy (\k v -> k % 2) (fromList [ ( 1, 1 ), ( 2, 2 ), ( 3, 3 ) ])) (fromList [ ( 1, [ 1, 3 ] ), ( 0, [ 2 ] ) ]) + ] + , describe "fromListBy" + [ test "empty" <| \() -> Expect.equal (fromListBy (\k v -> k) empty) empty + , test "simple list" <| \() -> Expect.equal (fromListBy (\k v -> k + 1) (fromList [ ( 1, 1 ), ( 2, 2 ), ( 3, 3 ) ])) (fromList [ ( 2, 1 ), ( 3, 2 ), ( 4, 3 ) ]) + ] + , describe "removeWhen" + [ test "empty" <| \() -> Expect.equal (removeWhen (\k v -> True) empty) empty + , test "remove all" <| \() -> Expect.equal (removeWhen (\k v -> True) (fromList [ ( 1, 1 ), ( 2, 2 ), ( 3, 3 ) ])) empty + , test "remove none" <| \() -> Expect.equal (removeWhen (\k v -> False) (fromList [ ( 1, 1 ), ( 2, 2 ), ( 3, 3 ) ])) (fromList [ ( 1, 1 ), ( 2, 2 ), ( 3, 3 ) ]) + ] + , describe "removeMany" + [ test "empty" <| \() -> Expect.equal (removeMany (Set.fromList [ 1, 2 ]) empty) empty + , test "remove none element" <| \() -> Expect.equal (removeMany (Set.fromList [ 4 ]) threeElementList) threeElementList + , test "remove one element" <| \() -> Expect.equal (removeMany (Set.fromList [ 1 ]) threeElementList) (DictList.filter (\k v -> k /= 1) threeElementList) + , test "remove two elements" <| \() -> Expect.equal (removeMany (Set.fromList [ 1, 2 ]) threeElementList) (DictList.filter (\k v -> k == 3) threeElementList) + , test "remove all elements" <| \() -> Expect.equal (removeMany (Set.fromList [ 1, 2, 3 ]) threeElementList) empty + ] + , describe "keepOnly" + [ test "empty" <| \() -> Expect.equal (keepOnly (Set.fromList [ 1, 2 ]) empty) empty + , test "keep none element" <| \() -> Expect.equal (removeMany (Set.fromList [ 4 ]) threeElementList) threeElementList + , test "keep one element" <| \() -> Expect.equal (keepOnly (Set.fromList [ 1 ]) threeElementList) (DictList.filter (\k v -> k == 1) threeElementList) + , test "keep two elements" <| \() -> Expect.equal (keepOnly (Set.fromList [ 1, 2 ]) threeElementList) (DictList.filter (\k v -> k /= 3) threeElementList) + , test "keep all elements" <| \() -> Expect.equal (keepOnly (Set.fromList [ 1, 2, 3 ]) threeElementList) threeElementList + ] + , describe "mapKeys" + [ test "empty" <| \() -> Expect.equal (mapKeys toString empty) empty + , test "toString mapping" <| \() -> Expect.equal (mapKeys toString threeElementList) (fromList [ ( "1", 1 ), ( "2", 2 ), ( "3", 3 ) ]) + ] + ] + + +dictExtraFuzzTests : Test +dictExtraFuzzTests = + -- @TODO Expand the fuzz tests + describe "Dict extra fuzz tests" + [ fuzz fuzzIntDictList "groupBy (total length doesn't change)" <| + \subject -> + Expect.equal (DictList.length subject) + (groupBy (\k v -> k % 2) subject + |> toList + |> List.map (\( k, v ) -> List.length v) + |> List.foldr (+) 0 + ) + , fuzz fuzzIntDictList "groupBy (no elements dissapear)" <| + \subject -> + Expect.equal + (Set.diff (Set.fromList (values subject)) + (Set.fromList + (groupBy (\k v -> k % 2) subject + |> toList + |> List.foldr (\( k, v ) agg -> List.append v agg) [] + ) + ) + ) + (Set.fromList []) + ] diff --git a/tests/src/Main.elm b/tests/src/Main.elm index 74de67d..e5870db 100644 --- a/tests/src/Main.elm +++ b/tests/src/Main.elm @@ -2,6 +2,7 @@ port module Main exposing (..) import DictTests import DictListTests +import DictExtraTests import Json.Encode exposing (Value) import ListTests import Test exposing (..) @@ -20,5 +21,6 @@ all = describe "All tests" [ DictListTests.tests , DictTests.tests + , DictExtraTests.tests , ListTests.tests ] From 966183d10719dc6ed474fa428cb3e098e36e7ac2 Mon Sep 17 00:00:00 2001 From: Daniel Wehner Date: Tue, 21 Mar 2017 08:51:27 +0100 Subject: [PATCH 2/6] Fix documentation --- src/DictList.elm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/DictList.elm b/src/DictList.elm index f69d463..085a4e0 100644 --- a/src/DictList.elm +++ b/src/DictList.elm @@ -952,7 +952,7 @@ Creates a `Dict` which maps the key to a list of matching elements. mary = {id=1, name="Mary"} jack = {id=2, name="Jack"} jill = {id=1, name="Jill"} - groupBy .id [mary, jack, jill] == Dict.fromList [(1, [mary, jill]), (2, [jack])] + groupBy .id [mary, jack, jill] == DictList.fromList [(1, [mary, jill]), (2, [jack])] -} groupBy : (comparable1 -> a -> comparable2) -> DictList comparable1 a -> DictList comparable2 (List a) groupBy keyfn list = @@ -970,7 +970,7 @@ This can, for instance, be useful when constructing Dicts from a List of records mary = {id=1, name="Mary"} jack = {id=2, name="Jack"} jill = {id=1, name="Jill"} - fromListBy .id [mary, jack, jill] == Dict.fromList [(1, jack), (2, jill)] + fromListBy .id [mary, jack, jill] == DictList.fromList [(1, jack), (2, jill)] -} fromListBy : (comparable1 -> a -> comparable2) -> DictList comparable1 a -> DictList comparable2 a fromListBy keyfn xs = @@ -981,7 +981,7 @@ fromListBy keyfn xs = {-| Remove elements which satisfies the predicate. - removeWhen (\_ v -> v == 1) (Dict.fromList [("Mary", 1), ("Jack", 2), ("Jill", 1)]) == Dict.fromList [("Jack", 2)] + removeWhen (\_ v -> v == 1) (DictList.fromList [("Mary", 1), ("Jack", 2), ("Jill", 1)]) == DictList.fromList [("Jack", 2)] -} removeWhen : (comparable -> v -> Bool) -> DictList comparable v -> DictList comparable v removeWhen pred dict = From b1fb8bdde5689c2c86532bac8d27d4c7379efc51 Mon Sep 17 00:00:00 2001 From: Daniel Wehner Date: Tue, 28 Mar 2017 14:06:50 +0200 Subject: [PATCH 3/6] Adapt groupBy/fromListBy to be more like the DictExtra variant --- src/DictList.elm | 14 +++++++------- tests/src/DictExtraTests.elm | 30 +++++++++++++++--------------- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/src/DictList.elm b/src/DictList.elm index 085a4e0..c6b8d39 100644 --- a/src/DictList.elm +++ b/src/DictList.elm @@ -954,11 +954,11 @@ Creates a `Dict` which maps the key to a list of matching elements. jill = {id=1, name="Jill"} groupBy .id [mary, jack, jill] == DictList.fromList [(1, [mary, jill]), (2, [jack])] -} -groupBy : (comparable1 -> a -> comparable2) -> DictList comparable1 a -> DictList comparable2 (List a) +groupBy : (a -> comparable) -> List a -> DictList comparable (List a) groupBy keyfn list = - foldr - (\key x acc -> - update (keyfn key x) (Maybe.map ((::) x) >> Maybe.withDefault [ x ] >> Just) acc + List.foldr + (\x acc -> + update (keyfn x) (Maybe.map ((::) x) >> Maybe.withDefault [ x ] >> Just) acc ) empty list @@ -972,10 +972,10 @@ This can, for instance, be useful when constructing Dicts from a List of records jill = {id=1, name="Jill"} fromListBy .id [mary, jack, jill] == DictList.fromList [(1, jack), (2, jill)] -} -fromListBy : (comparable1 -> a -> comparable2) -> DictList comparable1 a -> DictList comparable2 a +fromListBy : ( a -> comparable) -> List a -> DictList comparable a fromListBy keyfn xs = - foldl - (\key x acc -> insert (keyfn key x) x acc) + List.foldl + (\x acc -> insert (keyfn x) x acc) empty xs diff --git a/tests/src/DictExtraTests.elm b/tests/src/DictExtraTests.elm index 96cb334..e62a871 100644 --- a/tests/src/DictExtraTests.elm +++ b/tests/src/DictExtraTests.elm @@ -16,9 +16,9 @@ fuzzDictList fuzzKey fuzzValue = |> Fuzz.map DictList.fromList -fuzzIntDictList : Fuzzer (DictList Int Int) -fuzzIntDictList = - fuzzDictList Fuzz.int Fuzz.int +fuzzIntList : Fuzzer (List Int) +fuzzIntList = + Fuzz.list Fuzz.int threeElementList = @@ -36,14 +36,14 @@ dictExtraUnitTests : Test dictExtraUnitTests = describe "Dict Extra Unittests" [ describe "groupBy" - [ test "empty" <| \() -> Expect.equal (groupBy (\k v -> k) empty) empty - , test "always equal elements" <| \() -> Expect.equal (groupBy (\k v -> 1) (fromList [ ( 1, 1 ), ( 2, 2 ), ( 3, 3 ) ])) (fromList [ ( 1, [ 1, 2, 3 ] ) ]) - , test "map to original key" <| \() -> Expect.equal (groupBy (\k v -> k) (fromList [ ( 1, 1 ), ( 2, 2 ), ( 3, 3 ) ])) (fromList [ ( 3, [ 3 ] ), ( 2, [ 2 ] ), ( 1, [ 1 ] ) ]) - , test "odd-even" <| \() -> Expect.equal (groupBy (\k v -> k % 2) (fromList [ ( 1, 1 ), ( 2, 2 ), ( 3, 3 ) ])) (fromList [ ( 1, [ 1, 3 ] ), ( 0, [ 2 ] ) ]) + [ test "empty" <| \() -> Expect.equal (groupBy identity []) empty + , test "always equal elements" <| \() -> Expect.equal (groupBy (always 1) [1, 2, 3]) (fromList [ ( 1, [ 1, 2, 3 ] ) ]) + , test "map to original key" <| \() -> Expect.equal (groupBy identity [1, 2, 3]) (fromList [ ( 3, [ 3 ] ), ( 2, [ 2 ] ), ( 1, [ 1 ] ) ]) + , test "odd-even" <| \() -> Expect.equal (groupBy (\v -> v % 2) [1, 2, 3]) (fromList [ ( 1, [ 1, 3 ] ), ( 0, [ 2 ] ) ]) ] , describe "fromListBy" - [ test "empty" <| \() -> Expect.equal (fromListBy (\k v -> k) empty) empty - , test "simple list" <| \() -> Expect.equal (fromListBy (\k v -> k + 1) (fromList [ ( 1, 1 ), ( 2, 2 ), ( 3, 3 ) ])) (fromList [ ( 2, 1 ), ( 3, 2 ), ( 4, 3 ) ]) + [ test "empty" <| \() -> Expect.equal (fromListBy identity []) empty + , test "simple list" <| \() -> Expect.equal (fromListBy (\v ->v + 1) [1, 2, 3]) (fromList [ ( 2, 1 ), ( 3, 2 ), ( 4, 3 ) ]) ] , describe "removeWhen" [ test "empty" <| \() -> Expect.equal (removeWhen (\k v -> True) empty) empty @@ -75,20 +75,20 @@ dictExtraFuzzTests : Test dictExtraFuzzTests = -- @TODO Expand the fuzz tests describe "Dict extra fuzz tests" - [ fuzz fuzzIntDictList "groupBy (total length doesn't change)" <| + [ fuzz fuzzIntList "groupBy (total length doesn't change)" <| \subject -> - Expect.equal (DictList.length subject) - (groupBy (\k v -> k % 2) subject + Expect.equal (List.length subject) + (groupBy (\v -> v % 2) subject |> toList |> List.map (\( k, v ) -> List.length v) |> List.foldr (+) 0 ) - , fuzz fuzzIntDictList "groupBy (no elements dissapear)" <| + , fuzz fuzzIntList "groupBy (no elements dissapear)" <| \subject -> Expect.equal - (Set.diff (Set.fromList (values subject)) + (Set.diff (Set.fromList subject) (Set.fromList - (groupBy (\k v -> k % 2) subject + (groupBy (\v -> v % 2) subject |> toList |> List.foldr (\( k, v ) agg -> List.append v agg) [] ) From 964c128a8ec0fd6628d3bbb8cc0245469453b51c Mon Sep 17 00:00:00 2001 From: Daniel Wehner Date: Tue, 28 Mar 2017 14:07:08 +0200 Subject: [PATCH 4/6] Copy the DictExtra tests --- tests/src/DictExtraPackageTests.elm | 131 ++++++++++++++++++++++++++++ tests/src/Main.elm | 2 + 2 files changed, 133 insertions(+) create mode 100644 tests/src/DictExtraPackageTests.elm diff --git a/tests/src/DictExtraPackageTests.elm b/tests/src/DictExtraPackageTests.elm new file mode 100644 index 0000000..783bdbf --- /dev/null +++ b/tests/src/DictExtraPackageTests.elm @@ -0,0 +1,131 @@ +module DictExtraPackageTests exposing (tests) + +import Test.Runner.Node exposing (run, TestProgram) +import Test exposing (Test, describe, test, fuzz, fuzz2) +import Fuzz exposing (Fuzzer, intRange) +import Expect +import Json.Encode exposing (Value) +import Dict +import DictList exposing (..) +import Set + + +tests : Test +tests = + describe "Dict tests" + [ groupByTests + , fromListByTests + , removeWhenTests + , removeManyTests + , keepOnlyTests + , mapKeysTests + ] + + + +-- groupBy + + +groupByTests : Test +groupByTests = + describe "groupBy" + [ test "example" <| + \() -> + DictList.toList (groupBy .id [ mary, jack, jill ]) + |> Expect.equal [ ( 1, [ mary, jill ] ), ( 2, [ jack ] ) ] + ] + + +type alias GroupByData = + { id : Int + , name : String + } + + +mary : GroupByData +mary = + GroupByData 1 "Mary" + + +jack : GroupByData +jack = + GroupByData 2 "Jack" + + +jill : GroupByData +jill = + GroupByData 1 "Jill" + + + +-- fromListBy + + +fromListByTests : Test +fromListByTests = + describe "fromListBy" + [ test "example" <| + \() -> + fromListBy .id [ jack, jill ] + |> Expect.equal (DictList.fromList [ ( 2, jack ), ( 1, jill ) ]) + , test "replacement" <| + \() -> + fromListBy .id [ jack, jill, mary ] + |> Expect.equal (DictList.fromList [ ( 2, jack ), ( 1, mary ) ]) + ] + + + +-- removeWhen + + +removeWhenTests : Test +removeWhenTests = + describe "removeWhen" + [ test "example" <| + \() -> + removeWhen (\_ v -> v == 1) (DictList.fromList [ ( "Mary", 1 ), ( "Jack", 2 ), ( "Jill", 1 ) ]) + |> Expect.equal (DictList.fromList [ ( "Jack", 2 ) ]) + ] + + + +-- removeMany + + +removeManyTests : Test +removeManyTests = + describe "removeMany" + [ test "example" <| + \() -> + removeMany (Set.fromList [ "Mary", "Jill" ]) (DictList.fromList [ ( "Mary", 1 ), ( "Jack", 2 ), ( "Jill", 1 ) ]) + |> Expect.equal (DictList.fromList [ ( "Jack", 2 ) ]) + ] + + + +-- keepOnly + + +keepOnlyTests : Test +keepOnlyTests = + describe "keepOnly" + [ test "example" <| + \() -> + keepOnly (Set.fromList [ "Jack", "Jill" ]) (DictList.fromList [ ( "Mary", 1 ), ( "Jack", 2 ), ( "Jill", 1 ) ]) + |> Expect.equal (DictList.fromList [ ( "Jack", 2 ), ( "Jill", 1 ) ]) + ] + + + +-- mapKeys + + +mapKeysTests : Test +mapKeysTests = + describe "mapKeys" + [ test "example" <| + \() -> + mapKeys ((+) 1) (DictList.fromList [ ( 1, "Jack" ), ( 2, "Jill" ) ]) + |> Expect.equal (DictList.fromList [ ( 2, "Jack" ), ( 3, "Jill" ) ]) + ] diff --git a/tests/src/Main.elm b/tests/src/Main.elm index e5870db..1ccd036 100644 --- a/tests/src/Main.elm +++ b/tests/src/Main.elm @@ -3,6 +3,7 @@ port module Main exposing (..) import DictTests import DictListTests import DictExtraTests +import DictExtraPackageTests import Json.Encode exposing (Value) import ListTests import Test exposing (..) @@ -22,5 +23,6 @@ all = [ DictListTests.tests , DictTests.tests , DictExtraTests.tests + , DictExtraPackageTests.tests , ListTests.tests ] From 96d3d97933d665993b9ba11a5f7053642e7fc041 Mon Sep 17 00:00:00 2001 From: Daniel Wehner Date: Tue, 28 Mar 2017 14:10:38 +0200 Subject: [PATCH 5/6] Expose Set.Set so the code is a bit better to read --- src/DictList.elm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/DictList.elm b/src/DictList.elm index c6b8d39..ea7eb04 100644 --- a/src/DictList.elm +++ b/src/DictList.elm @@ -130,7 +130,7 @@ import Dict exposing (Dict) import DictList.Compat exposing (customDecoder, decodeAndThen, first, maybeAndThen, second) import Json.Decode exposing (Decoder, keyValuePairs, value, decodeValue) import List.Extra -import Set +import Set exposing (Set) {-| A `Dict` that maintains an arbitrary ordering of keys (rather than sorting @@ -990,14 +990,14 @@ removeWhen pred dict = {-| Remove a key-value pair if its key appears in the set. -} -removeMany : Set.Set comparable -> DictList comparable v -> DictList comparable v +removeMany : Set comparable -> DictList comparable v -> DictList comparable v removeMany set dict = Set.foldl (\k acc -> remove k acc) dict set {-| Keep a key-value pair if its key appears in the set. -} -keepOnly : Set.Set comparable -> DictList comparable v -> DictList comparable v +keepOnly : Set comparable -> DictList comparable v -> DictList comparable v keepOnly set dict = Set.foldl (\k acc -> From d3156e065c841def62d6f8c0c93ecb2d7a3c7d78 Mon Sep 17 00:00:00 2001 From: Daniel Wehner Date: Tue, 28 Mar 2017 14:11:11 +0200 Subject: [PATCH 6/6] run elm-format --- src/DictList.elm | 2 +- tests/src/DictExtraTests.elm | 8 ++++---- tests/src/ListTests.elm | 10 +++++----- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/DictList.elm b/src/DictList.elm index ea7eb04..d21c80a 100644 --- a/src/DictList.elm +++ b/src/DictList.elm @@ -972,7 +972,7 @@ This can, for instance, be useful when constructing Dicts from a List of records jill = {id=1, name="Jill"} fromListBy .id [mary, jack, jill] == DictList.fromList [(1, jack), (2, jill)] -} -fromListBy : ( a -> comparable) -> List a -> DictList comparable a +fromListBy : (a -> comparable) -> List a -> DictList comparable a fromListBy keyfn xs = List.foldl (\x acc -> insert (keyfn x) x acc) diff --git a/tests/src/DictExtraTests.elm b/tests/src/DictExtraTests.elm index e62a871..6be42ee 100644 --- a/tests/src/DictExtraTests.elm +++ b/tests/src/DictExtraTests.elm @@ -37,13 +37,13 @@ dictExtraUnitTests = describe "Dict Extra Unittests" [ describe "groupBy" [ test "empty" <| \() -> Expect.equal (groupBy identity []) empty - , test "always equal elements" <| \() -> Expect.equal (groupBy (always 1) [1, 2, 3]) (fromList [ ( 1, [ 1, 2, 3 ] ) ]) - , test "map to original key" <| \() -> Expect.equal (groupBy identity [1, 2, 3]) (fromList [ ( 3, [ 3 ] ), ( 2, [ 2 ] ), ( 1, [ 1 ] ) ]) - , test "odd-even" <| \() -> Expect.equal (groupBy (\v -> v % 2) [1, 2, 3]) (fromList [ ( 1, [ 1, 3 ] ), ( 0, [ 2 ] ) ]) + , test "always equal elements" <| \() -> Expect.equal (groupBy (always 1) [ 1, 2, 3 ]) (fromList [ ( 1, [ 1, 2, 3 ] ) ]) + , test "map to original key" <| \() -> Expect.equal (groupBy identity [ 1, 2, 3 ]) (fromList [ ( 3, [ 3 ] ), ( 2, [ 2 ] ), ( 1, [ 1 ] ) ]) + , test "odd-even" <| \() -> Expect.equal (groupBy (\v -> v % 2) [ 1, 2, 3 ]) (fromList [ ( 1, [ 1, 3 ] ), ( 0, [ 2 ] ) ]) ] , describe "fromListBy" [ test "empty" <| \() -> Expect.equal (fromListBy identity []) empty - , test "simple list" <| \() -> Expect.equal (fromListBy (\v ->v + 1) [1, 2, 3]) (fromList [ ( 2, 1 ), ( 3, 2 ), ( 4, 3 ) ]) + , test "simple list" <| \() -> Expect.equal (fromListBy (\v -> v + 1) [ 1, 2, 3 ]) (fromList [ ( 2, 1 ), ( 3, 2 ), ( 4, 3 ) ]) ] , describe "removeWhen" [ test "empty" <| \() -> Expect.equal (removeWhen (\k v -> True) empty) empty diff --git a/tests/src/ListTests.elm b/tests/src/ListTests.elm index 49d0cf6..c87aea6 100644 --- a/tests/src/ListTests.elm +++ b/tests/src/ListTests.elm @@ -22,7 +22,7 @@ tests = toDictList : List comparable -> DictList comparable comparable toDictList = - List.map (\a -> (a, a)) >> DictList.fromList + List.map (\a -> ( a, a )) >> DictList.fromList testListOfN : Int -> Test @@ -40,7 +40,7 @@ testListOfN n = -- assume foldl and (::) work zs = List.range 0 n - |> List.map (\a -> (a, a)) + |> List.map (\a -> ( a, a )) |> DictList.fromList sumSeq k = @@ -77,7 +77,7 @@ testListOfN n = if n == 0 then Expect.equal (Nothing) (head xs) else - Expect.equal (Just (1, 1)) (head xs) + Expect.equal (Just ( 1, 1 )) (head xs) , describe "List.filter" [ test "none" <| \() -> Expect.equal (empty) (DictList.filter (\_ x -> x > n) xs) , test "one" <| \() -> Expect.equal [ n ] (values <| DictList.filter (\_ z -> z == n) zs) @@ -95,8 +95,8 @@ testListOfN n = , test "all" <| \() -> Expect.equal (empty) (drop n xs) , test "all+" <| \() -> Expect.equal (empty) (drop (n + 1) xs) ] - -- append works differently in `DictList` because it overwrites things with the same keys - , test "append" <| \() -> Expect.equal (xsSum {- * 2-}) (append xs xs |> foldl (always (+)) 0) + -- append works differently in `DictList` because it overwrites things with the same keys + , test "append" <| \() -> Expect.equal (xsSum {- * 2 -}) (append xs xs |> foldl (always (+)) 0) , test "cons" <| \() -> Expect.equal (values <| append (toDictList [ -1 ]) xs) (values <| cons -1 -1 xs) , test "List.concat" <| \() -> Expect.equal (append xs (append zs xs)) (DictList.concat [ xs, zs, xs ]) , describe "partition"