summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEugen Wissner <belka@caraus.de>2021-02-13 06:56:10 +0100
committerEugen Wissner <belka@caraus.de>2021-02-13 06:56:10 +0100
commitc1a1b47aeae5846661a83a43c05e4b4a1e24266a (patch)
treebaf401f02da5a8f1f7cd35e34f2eb71a48873219
parent1e8405a6d6de8d7a5a1323ba11e48fb4fb852b80 (diff)
downloadgraphql-c1a1b47aeae5846661a83a43c05e4b4a1e24266a.tar.gz
Add OrderedMap prototype
-rw-r--r--graphql.cabal6
-rw-r--r--package.yaml1
-rw-r--r--src/Language/GraphQL/Execute/OrderedMap.hs64
-rw-r--r--tests/Language/GraphQL/Execute/OrderedMapSpec.hs17
4 files changed, 87 insertions, 1 deletions
diff --git a/graphql.cabal b/graphql.cabal
index c06dba4..152af00 100644
--- a/graphql.cabal
+++ b/graphql.cabal
@@ -4,7 +4,7 @@ cabal-version: 2.2
--
-- see: https://github.com/sol/hpack
--
--- hash: 15a0880180192f918ba0bd3b3e955c57232f1efe8993745d505fcb6e1aab1451
+-- hash: dcf3c9aaaaef892c7f75781a0c181c77477fc5bb2757704494c398b99f7fb1c7
name: graphql
version: 0.11.1.0
@@ -43,6 +43,7 @@ library
Language.GraphQL.Error
Language.GraphQL.Execute
Language.GraphQL.Execute.Coerce
+ Language.GraphQL.Execute.OrderedMap
Language.GraphQL.Type
Language.GraphQL.Type.In
Language.GraphQL.Type.Out
@@ -72,6 +73,7 @@ library
, text
, transformers
, unordered-containers
+ , vector
default-language: Haskell2010
test-suite graphql-test
@@ -84,6 +86,7 @@ test-suite graphql-test
Language.GraphQL.AST.ParserSpec
Language.GraphQL.ErrorSpec
Language.GraphQL.Execute.CoerceSpec
+ Language.GraphQL.Execute.OrderedMapSpec
Language.GraphQL.ExecuteSpec
Language.GraphQL.Type.OutSpec
Language.GraphQL.Validate.RulesSpec
@@ -114,4 +117,5 @@ test-suite graphql-test
, text
, transformers
, unordered-containers
+ , vector
default-language: Haskell2010
diff --git a/package.yaml b/package.yaml
index da9eefd..448353e 100644
--- a/package.yaml
+++ b/package.yaml
@@ -38,6 +38,7 @@ dependencies:
- text
- transformers
- unordered-containers
+- vector
library:
source-dirs: src
diff --git a/src/Language/GraphQL/Execute/OrderedMap.hs b/src/Language/GraphQL/Execute/OrderedMap.hs
new file mode 100644
index 0000000..ae50dd3
--- /dev/null
+++ b/src/Language/GraphQL/Execute/OrderedMap.hs
@@ -0,0 +1,64 @@
+{- This Source Code Form is subject to the terms of the Mozilla Public License,
+ v. 2.0. If a copy of the MPL was not distributed with this file, You can
+ obtain one at https://mozilla.org/MPL/2.0/. -}
+
+{-# LANGUAGE ExplicitForAll #-}
+module Language.GraphQL.Execute.OrderedMap
+ ( OrderedMap
+ , singleton
+ ) where
+
+import Data.HashMap.Strict (HashMap)
+import qualified Data.HashMap.Strict as HashMap
+import Data.Text (Text)
+import Data.Vector (Vector)
+import qualified Data.Vector as Vector
+
+data OrderedMap v = OrderedMap (Vector Text) (HashMap Text v)
+
+instance Functor OrderedMap where
+ fmap f (OrderedMap vector hashMap) = OrderedMap vector $ fmap f hashMap
+
+instance Foldable OrderedMap where
+ foldr f = foldrWithKey $ const f
+ null (OrderedMap vector _) = Vector.null vector
+
+instance Show v => Show (OrderedMap v) where
+ showsPrec precedence map' = showParen (precedence > 10)
+ $ showString "fromList " . shows (toList map')
+
+instance Semigroup (OrderedMap v) where
+ (<>) = foldrWithKey go
+ where
+ go key value accumulator@(OrderedMap vector hashMap)
+ | Nothing <- HashMap.lookup key hashMap
+ = OrderedMap (Vector.snoc vector key)
+ $ HashMap.insert key value hashMap
+ | otherwise = accumulator
+
+instance Monoid (OrderedMap v) where
+ mempty = OrderedMap mempty mempty
+
+-- * Construction
+
+-- | Constructs a map with a single element.
+singleton :: forall v. Text -> v -> OrderedMap v
+singleton key value = OrderedMap (Vector.singleton key)
+ $ HashMap.singleton key value
+
+-- * Folds
+
+-- | Reduces this map by applying a binary operator to all elements, using the
+-- given starting value.
+foldrWithKey :: forall v a. (Text -> v -> a -> a) -> a -> OrderedMap v -> a
+foldrWithKey f initial (OrderedMap vector hashMap) = foldr go initial vector
+ where
+ go key accumulator = f key (hashMap HashMap.! key) accumulator
+
+-- * Lists
+
+-- | Converts this map to the list of key-value pairs.
+toList :: forall v. OrderedMap v -> [(Text, v)]
+toList = foldrWithKey f []
+ where
+ f key value accumulator = (key, value) : accumulator
diff --git a/tests/Language/GraphQL/Execute/OrderedMapSpec.hs b/tests/Language/GraphQL/Execute/OrderedMapSpec.hs
new file mode 100644
index 0000000..35d311c
--- /dev/null
+++ b/tests/Language/GraphQL/Execute/OrderedMapSpec.hs
@@ -0,0 +1,17 @@
+{- This Source Code Form is subject to the terms of the Mozilla Public License,
+ v. 2.0. If a copy of the MPL was not distributed with this file, You can
+ obtain one at https://mozilla.org/MPL/2.0/. -}
+
+{-# LANGUAGE OverloadedStrings #-}
+module Language.GraphQL.Execute.OrderedMapSpec
+ ( spec
+ ) where
+
+import Language.GraphQL.Execute.OrderedMap (OrderedMap)
+import Test.Hspec (Spec, describe, it, shouldSatisfy)
+
+spec :: Spec
+spec =
+ describe "OrderedMap" $
+ it "creates an empty map" $
+ (mempty :: OrderedMap Int) `shouldSatisfy` null