summaryrefslogtreecommitdiff
path: root/src/Language/GraphQL/Type.hs
diff options
context:
space:
mode:
authorEugen Wissner <belka@caraus.de>2019-07-05 20:05:04 +0200
committerEugen Wissner <belka@caraus.de>2019-07-05 20:05:04 +0200
commitd7b6fd0329717ca8ae98db9993581ca493a3784f (patch)
tree6281425a96824737e701ccb2dfecf47de228d867 /src/Language/GraphQL/Type.hs
parent2fa50d4f6290a39e492043eaeed8ede8e26ce62d (diff)
downloadgraphql-d7b6fd0329717ca8ae98db9993581ca493a3784f.tar.gz
Allow resolvers to return arbitrary nested lists
Diffstat (limited to 'src/Language/GraphQL/Type.hs')
-rw-r--r--src/Language/GraphQL/Type.hs57
1 files changed, 57 insertions, 0 deletions
diff --git a/src/Language/GraphQL/Type.hs b/src/Language/GraphQL/Type.hs
new file mode 100644
index 0000000..3f91e50
--- /dev/null
+++ b/src/Language/GraphQL/Type.hs
@@ -0,0 +1,57 @@
+-- | Definitions for @GraphQL@ type system.
+module Language.GraphQL.Type
+ ( Wrapping(..)
+ ) where
+
+import Data.Aeson as Aeson ( ToJSON
+ , toJSON
+ )
+import qualified Data.Aeson as Aeson
+
+-- | GraphQL distinguishes between "wrapping" and "named" types. Each wrapping
+-- type can wrap other wrapping or named types. Wrapping types are lists and
+-- Non-Null types (named types are nullable by default).
+--
+-- This 'Wrapping' type doesn\'t reflect this distinction exactly but it is
+-- used in the resolvers to take into account that the returned value can be
+-- nullable or an (arbitrary nested) list.
+data Wrapping a
+ = List [Wrapping a] -- ^ Arbitrary nested list
+ | Named a -- ^ Named type without further wrapping
+ | Null -- ^ Null
+ deriving (Eq, Show)
+
+instance Functor Wrapping where
+ fmap f (List list) = List $ fmap (fmap f) list
+ fmap f (Named named) = Named $ f named
+ fmap _ Null = Null
+
+instance Foldable Wrapping where
+ foldr f acc (List list) = foldr (flip $ foldr f) acc list
+ foldr f acc (Named named) = f named acc
+ foldr _ acc Null = acc
+
+instance Traversable Wrapping where
+ traverse f (List list) = List <$> traverse (traverse f) list
+ traverse f (Named named) = Named <$> f named
+ traverse _ Null = pure Null
+
+instance Applicative Wrapping where
+ pure = Named
+ Null <*> _ = Null
+ _ <*> Null = Null
+ (Named f) <*> (Named x) = Named $ f x
+ (List fs) <*> (List xs) = List $ (<*>) <$> fs <*> xs
+ (Named f) <*> list = f <$> list
+ (List fs) <*> named = List $ (<*> named) <$> fs
+
+instance Monad Wrapping where
+ return = pure
+ Null >>= _ = Null
+ (Named x) >>= f = f x
+ (List xs) >>= f = List $ fmap (>>= f) xs
+
+instance ToJSON a => ToJSON (Wrapping a) where
+ toJSON (List list) = toJSON list
+ toJSON (Named named) = toJSON named
+ toJSON Null = Aeson.Null