{-# LANGUAGE GeneralizedNewtypeDeriving, DeriveTraversable, TypeFamilies, OverloadedStrings #-}
-- |
-- Module: Data.Greskell.PMap
-- Description: Property map, a map with Text keys and cardinality options
-- Maintainer: Toshio Ito <debug.ito@gmail.com>
--
-- This module defines 'PMap', a map with 'Text' keys and cardinality
-- options. 
--
-- @since 1.0.0.0
module Data.Greskell.PMap
  ( -- * PMap
    PMap,
    -- ** Single lookup
    lookup,
    lookupM,
    lookupAs,
    lookupAs',
    lookupAsM,
    -- ** List lookup
    lookupList,
    lookupListAs,
    lookupListAs',
    -- ** Others
    pMapInsert,
    pMapDelete,
    pMapLookup,
    pMapToList,
    pMapFromList,
    -- * Cardinality
    Single,
    Multi,
    -- * PMapKey
    PMapKey(..),
    -- * Errors
    PMapLookupException(..),
    pMapDecribeError,
    pMapToThrow,
    pMapToFail
  ) where

import Prelude hiding (lookup)

import Control.Exception (Exception)
import Control.Monad.Catch (MonadThrow(..), MonadCatch(..))
import Control.Monad.Fail (MonadFail)
import Data.Aeson.Types (Parser)
import qualified Data.Foldable as F
import Data.Functor.Identity (Identity)
import Data.Greskell.AsIterator (AsIterator(..))
import Data.Greskell.GMap (GMapEntry)
import Data.Greskell.GraphSON (GValue, GraphSONTyped(..), FromGraphSON(..), parseEither)
import qualified Data.HashMap.Strict as HM
import Data.List.NonEmpty (NonEmpty((:|)))
import Data.Maybe (listToMaybe)
import Data.Monoid (Monoid(..))
import Data.Semigroup (Semigroup((<>)))
import qualified Data.Semigroup as S
import Data.Traversable (Traversable(traverse))
import Data.Text (Text, unpack)

import Data.Greskell.NonEmptyLike (NonEmptyLike)
import qualified Data.Greskell.NonEmptyLike as NEL

-- | A property map, which has text keys and @v@ values. @c@ specifies
-- the cardinality of each item, and should be an instance of
-- 'NonEmptyLike'.
--
-- You can look up values from 'PMap' using key types of 'PMapKey'
-- class.
--
-- @since 1.0.0.0
newtype PMap c v = PMap (HM.HashMap Text (c v))
                 deriving (Int -> PMap c v -> ShowS
[PMap c v] -> ShowS
PMap c v -> String
(Int -> PMap c v -> ShowS)
-> (PMap c v -> String) -> ([PMap c v] -> ShowS) -> Show (PMap c v)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall (c :: * -> *) v. Show (c v) => Int -> PMap c v -> ShowS
forall (c :: * -> *) v. Show (c v) => [PMap c v] -> ShowS
forall (c :: * -> *) v. Show (c v) => PMap c v -> String
showList :: [PMap c v] -> ShowS
$cshowList :: forall (c :: * -> *) v. Show (c v) => [PMap c v] -> ShowS
show :: PMap c v -> String
$cshow :: forall (c :: * -> *) v. Show (c v) => PMap c v -> String
showsPrec :: Int -> PMap c v -> ShowS
$cshowsPrec :: forall (c :: * -> *) v. Show (c v) => Int -> PMap c v -> ShowS
Show,PMap c v -> PMap c v -> Bool
(PMap c v -> PMap c v -> Bool)
-> (PMap c v -> PMap c v -> Bool) -> Eq (PMap c v)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall (c :: * -> *) v. Eq (c v) => PMap c v -> PMap c v -> Bool
/= :: PMap c v -> PMap c v -> Bool
$c/= :: forall (c :: * -> *) v. Eq (c v) => PMap c v -> PMap c v -> Bool
== :: PMap c v -> PMap c v -> Bool
$c== :: forall (c :: * -> *) v. Eq (c v) => PMap c v -> PMap c v -> Bool
Eq,a -> PMap c b -> PMap c a
(a -> b) -> PMap c a -> PMap c b
(forall a b. (a -> b) -> PMap c a -> PMap c b)
-> (forall a b. a -> PMap c b -> PMap c a) -> Functor (PMap c)
forall a b. a -> PMap c b -> PMap c a
forall a b. (a -> b) -> PMap c a -> PMap c b
forall (c :: * -> *) a b. Functor c => a -> PMap c b -> PMap c a
forall (c :: * -> *) a b.
Functor c =>
(a -> b) -> PMap c a -> PMap c b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: a -> PMap c b -> PMap c a
$c<$ :: forall (c :: * -> *) a b. Functor c => a -> PMap c b -> PMap c a
fmap :: (a -> b) -> PMap c a -> PMap c b
$cfmap :: forall (c :: * -> *) a b.
Functor c =>
(a -> b) -> PMap c a -> PMap c b
Functor,PMap c a -> Bool
(a -> m) -> PMap c a -> m
(a -> b -> b) -> b -> PMap c a -> b
(forall m. Monoid m => PMap c m -> m)
-> (forall m a. Monoid m => (a -> m) -> PMap c a -> m)
-> (forall m a. Monoid m => (a -> m) -> PMap c a -> m)
-> (forall a b. (a -> b -> b) -> b -> PMap c a -> b)
-> (forall a b. (a -> b -> b) -> b -> PMap c a -> b)
-> (forall b a. (b -> a -> b) -> b -> PMap c a -> b)
-> (forall b a. (b -> a -> b) -> b -> PMap c a -> b)
-> (forall a. (a -> a -> a) -> PMap c a -> a)
-> (forall a. (a -> a -> a) -> PMap c a -> a)
-> (forall a. PMap c a -> [a])
-> (forall a. PMap c a -> Bool)
-> (forall a. PMap c a -> Int)
-> (forall a. Eq a => a -> PMap c a -> Bool)
-> (forall a. Ord a => PMap c a -> a)
-> (forall a. Ord a => PMap c a -> a)
-> (forall a. Num a => PMap c a -> a)
-> (forall a. Num a => PMap c a -> a)
-> Foldable (PMap c)
forall a. Eq a => a -> PMap c a -> Bool
forall a. Num a => PMap c a -> a
forall a. Ord a => PMap c a -> a
forall m. Monoid m => PMap c m -> m
forall a. PMap c a -> Bool
forall a. PMap c a -> Int
forall a. PMap c a -> [a]
forall a. (a -> a -> a) -> PMap c a -> a
forall m a. Monoid m => (a -> m) -> PMap c a -> m
forall b a. (b -> a -> b) -> b -> PMap c a -> b
forall a b. (a -> b -> b) -> b -> PMap c a -> b
forall (c :: * -> *) a. (Foldable c, Eq a) => a -> PMap c a -> Bool
forall (c :: * -> *) a. (Foldable c, Num a) => PMap c a -> a
forall (c :: * -> *) a. (Foldable c, Ord a) => PMap c a -> a
forall (c :: * -> *) m. (Foldable c, Monoid m) => PMap c m -> m
forall (c :: * -> *) a. Foldable c => PMap c a -> Bool
forall (c :: * -> *) a. Foldable c => PMap c a -> Int
forall (c :: * -> *) a. Foldable c => PMap c a -> [a]
forall (c :: * -> *) a.
Foldable c =>
(a -> a -> a) -> PMap c a -> a
forall (c :: * -> *) m a.
(Foldable c, Monoid m) =>
(a -> m) -> PMap c a -> m
forall (c :: * -> *) b a.
Foldable c =>
(b -> a -> b) -> b -> PMap c a -> b
forall (c :: * -> *) a b.
Foldable c =>
(a -> b -> b) -> b -> PMap c a -> b
forall (t :: * -> *).
(forall m. Monoid m => t m -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. t a -> [a])
-> (forall a. t a -> Bool)
-> (forall a. t a -> Int)
-> (forall a. Eq a => a -> t a -> Bool)
-> (forall a. Ord a => t a -> a)
-> (forall a. Ord a => t a -> a)
-> (forall a. Num a => t a -> a)
-> (forall a. Num a => t a -> a)
-> Foldable t
product :: PMap c a -> a
$cproduct :: forall (c :: * -> *) a. (Foldable c, Num a) => PMap c a -> a
sum :: PMap c a -> a
$csum :: forall (c :: * -> *) a. (Foldable c, Num a) => PMap c a -> a
minimum :: PMap c a -> a
$cminimum :: forall (c :: * -> *) a. (Foldable c, Ord a) => PMap c a -> a
maximum :: PMap c a -> a
$cmaximum :: forall (c :: * -> *) a. (Foldable c, Ord a) => PMap c a -> a
elem :: a -> PMap c a -> Bool
$celem :: forall (c :: * -> *) a. (Foldable c, Eq a) => a -> PMap c a -> Bool
length :: PMap c a -> Int
$clength :: forall (c :: * -> *) a. Foldable c => PMap c a -> Int
null :: PMap c a -> Bool
$cnull :: forall (c :: * -> *) a. Foldable c => PMap c a -> Bool
toList :: PMap c a -> [a]
$ctoList :: forall (c :: * -> *) a. Foldable c => PMap c a -> [a]
foldl1 :: (a -> a -> a) -> PMap c a -> a
$cfoldl1 :: forall (c :: * -> *) a.
Foldable c =>
(a -> a -> a) -> PMap c a -> a
foldr1 :: (a -> a -> a) -> PMap c a -> a
$cfoldr1 :: forall (c :: * -> *) a.
Foldable c =>
(a -> a -> a) -> PMap c a -> a
foldl' :: (b -> a -> b) -> b -> PMap c a -> b
$cfoldl' :: forall (c :: * -> *) b a.
Foldable c =>
(b -> a -> b) -> b -> PMap c a -> b
foldl :: (b -> a -> b) -> b -> PMap c a -> b
$cfoldl :: forall (c :: * -> *) b a.
Foldable c =>
(b -> a -> b) -> b -> PMap c a -> b
foldr' :: (a -> b -> b) -> b -> PMap c a -> b
$cfoldr' :: forall (c :: * -> *) a b.
Foldable c =>
(a -> b -> b) -> b -> PMap c a -> b
foldr :: (a -> b -> b) -> b -> PMap c a -> b
$cfoldr :: forall (c :: * -> *) a b.
Foldable c =>
(a -> b -> b) -> b -> PMap c a -> b
foldMap' :: (a -> m) -> PMap c a -> m
$cfoldMap' :: forall (c :: * -> *) m a.
(Foldable c, Monoid m) =>
(a -> m) -> PMap c a -> m
foldMap :: (a -> m) -> PMap c a -> m
$cfoldMap :: forall (c :: * -> *) m a.
(Foldable c, Monoid m) =>
(a -> m) -> PMap c a -> m
fold :: PMap c m -> m
$cfold :: forall (c :: * -> *) m. (Foldable c, Monoid m) => PMap c m -> m
Foldable,Functor (PMap c)
Foldable (PMap c)
Functor (PMap c)
-> Foldable (PMap c)
-> (forall (f :: * -> *) a b.
    Applicative f =>
    (a -> f b) -> PMap c a -> f (PMap c b))
-> (forall (f :: * -> *) a.
    Applicative f =>
    PMap c (f a) -> f (PMap c a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> PMap c a -> m (PMap c b))
-> (forall (m :: * -> *) a.
    Monad m =>
    PMap c (m a) -> m (PMap c a))
-> Traversable (PMap c)
(a -> f b) -> PMap c a -> f (PMap c b)
forall (t :: * -> *).
Functor t
-> Foldable t
-> (forall (f :: * -> *) a b.
    Applicative f =>
    (a -> f b) -> t a -> f (t b))
-> (forall (f :: * -> *) a. Applicative f => t (f a) -> f (t a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> t a -> m (t b))
-> (forall (m :: * -> *) a. Monad m => t (m a) -> m (t a))
-> Traversable t
forall (c :: * -> *). Traversable c => Functor (PMap c)
forall (c :: * -> *). Traversable c => Foldable (PMap c)
forall (c :: * -> *) (m :: * -> *) a.
(Traversable c, Monad m) =>
PMap c (m a) -> m (PMap c a)
forall (c :: * -> *) (f :: * -> *) a.
(Traversable c, Applicative f) =>
PMap c (f a) -> f (PMap c a)
forall (c :: * -> *) (m :: * -> *) a b.
(Traversable c, Monad m) =>
(a -> m b) -> PMap c a -> m (PMap c b)
forall (c :: * -> *) (f :: * -> *) a b.
(Traversable c, Applicative f) =>
(a -> f b) -> PMap c a -> f (PMap c b)
forall (m :: * -> *) a. Monad m => PMap c (m a) -> m (PMap c a)
forall (f :: * -> *) a.
Applicative f =>
PMap c (f a) -> f (PMap c a)
forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> PMap c a -> m (PMap c b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> PMap c a -> f (PMap c b)
sequence :: PMap c (m a) -> m (PMap c a)
$csequence :: forall (c :: * -> *) (m :: * -> *) a.
(Traversable c, Monad m) =>
PMap c (m a) -> m (PMap c a)
mapM :: (a -> m b) -> PMap c a -> m (PMap c b)
$cmapM :: forall (c :: * -> *) (m :: * -> *) a b.
(Traversable c, Monad m) =>
(a -> m b) -> PMap c a -> m (PMap c b)
sequenceA :: PMap c (f a) -> f (PMap c a)
$csequenceA :: forall (c :: * -> *) (f :: * -> *) a.
(Traversable c, Applicative f) =>
PMap c (f a) -> f (PMap c a)
traverse :: (a -> f b) -> PMap c a -> f (PMap c b)
$ctraverse :: forall (c :: * -> *) (f :: * -> *) a b.
(Traversable c, Applicative f) =>
(a -> f b) -> PMap c a -> f (PMap c b)
$cp2Traversable :: forall (c :: * -> *). Traversable c => Foldable (PMap c)
$cp1Traversable :: forall (c :: * -> *). Traversable c => Functor (PMap c)
Traversable)

instance GraphSONTyped (PMap c v) where
  gsonTypeFor :: PMap c v -> Text
gsonTypeFor PMap c v
_ = Text
"g:Map"

instance FromGraphSON (c v) => FromGraphSON (PMap c v) where
  parseGraphSON :: GValue -> Parser (PMap c v)
parseGraphSON GValue
gv = (HashMap Text (c v) -> PMap c v)
-> Parser (HashMap Text (c v)) -> Parser (PMap c v)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap HashMap Text (c v) -> PMap c v
forall (c :: * -> *) v. HashMap Text (c v) -> PMap c v
PMap (Parser (HashMap Text (c v)) -> Parser (PMap c v))
-> Parser (HashMap Text (c v)) -> Parser (PMap c v)
forall a b. (a -> b) -> a -> b
$ GValue -> Parser (HashMap Text (c v))
forall a. FromGraphSON a => GValue -> Parser a
parseGraphSON GValue
gv

-- | Make a union of the two 'PMap's. If the two 'PMap's share some
-- keys, those values are merged by 'NEL.append' method from
-- 'NonEmptyLike'.
instance NonEmptyLike c => Semigroup (PMap c v) where
  (PMap HashMap Text (c v)
a) <> :: PMap c v -> PMap c v -> PMap c v
<> (PMap HashMap Text (c v)
b) = HashMap Text (c v) -> PMap c v
forall (c :: * -> *) v. HashMap Text (c v) -> PMap c v
PMap ((c v -> c v -> c v)
-> HashMap Text (c v) -> HashMap Text (c v) -> HashMap Text (c v)
forall k v.
(Eq k, Hashable k) =>
(v -> v -> v) -> HashMap k v -> HashMap k v -> HashMap k v
HM.unionWith c v -> c v -> c v
forall (t :: * -> *) a. NonEmptyLike t => t a -> t a -> t a
NEL.append HashMap Text (c v)
a HashMap Text (c v)
b)

instance NonEmptyLike c => Monoid (PMap c v) where
  mempty :: PMap c v
mempty = HashMap Text (c v) -> PMap c v
forall (c :: * -> *) v. HashMap Text (c v) -> PMap c v
PMap (HashMap Text (c v) -> PMap c v) -> HashMap Text (c v) -> PMap c v
forall a b. (a -> b) -> a -> b
$ HashMap Text (c v)
forall k v. HashMap k v
HM.empty
  mappend :: PMap c v -> PMap c v -> PMap c v
mappend = PMap c v -> PMap c v -> PMap c v
forall a. Semigroup a => a -> a -> a
(<>)

instance AsIterator (PMap c v) where
  type IteratorItem (PMap c v) = GMapEntry Text (c v)

-- | Insert a key-value pair to 'PMap'. If it already has some items
-- for that key, 'NEL.append' method of the 'NonEmptyLike' type @c@
-- determines its behavior.
pMapInsert :: NonEmptyLike c => Text -> v -> PMap c v -> PMap c v
pMapInsert :: Text -> v -> PMap c v -> PMap c v
pMapInsert Text
k v
v (PMap HashMap Text (c v)
hm) = HashMap Text (c v) -> PMap c v
forall (c :: * -> *) v. HashMap Text (c v) -> PMap c v
PMap (HashMap Text (c v) -> PMap c v) -> HashMap Text (c v) -> PMap c v
forall a b. (a -> b) -> a -> b
$ (c v -> c v -> c v)
-> Text -> c v -> HashMap Text (c v) -> HashMap Text (c v)
forall k v.
(Eq k, Hashable k) =>
(v -> v -> v) -> k -> v -> HashMap k v -> HashMap k v
HM.insertWith c v -> c v -> c v
forall (t :: * -> *) a. NonEmptyLike t => t a -> t a -> t a
NEL.append Text
k (v -> c v
forall (t :: * -> *) a. NonEmptyLike t => a -> t a
NEL.singleton v
v) HashMap Text (c v)
hm

-- | Delete a key and all values associated with it.
pMapDelete :: Text -> PMap c v -> PMap c v
pMapDelete :: Text -> PMap c v -> PMap c v
pMapDelete Text
k (PMap HashMap Text (c v)
hm) = HashMap Text (c v) -> PMap c v
forall (c :: * -> *) v. HashMap Text (c v) -> PMap c v
PMap (HashMap Text (c v) -> PMap c v) -> HashMap Text (c v) -> PMap c v
forall a b. (a -> b) -> a -> b
$ Text -> HashMap Text (c v) -> HashMap Text (c v)
forall k v. (Eq k, Hashable k) => k -> HashMap k v -> HashMap k v
HM.delete Text
k HashMap Text (c v)
hm

-- | Lookup all items for the key (low-level function). If there is no
-- item for the key, it returns an empty list.
pMapLookup :: NonEmptyLike c => Text -> PMap c v -> [v]
pMapLookup :: Text -> PMap c v -> [v]
pMapLookup Text
k (PMap HashMap Text (c v)
hm) = [v] -> (c v -> [v]) -> Maybe (c v) -> [v]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe [] (NonEmpty v -> [v]
forall (t :: * -> *) a. Foldable t => t a -> [a]
F.toList (NonEmpty v -> [v]) -> (c v -> NonEmpty v) -> c v -> [v]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. c v -> NonEmpty v
forall (t :: * -> *) a. NonEmptyLike t => t a -> NonEmpty a
NEL.toNonEmpty) (Maybe (c v) -> [v]) -> Maybe (c v) -> [v]
forall a b. (a -> b) -> a -> b
$ Text -> HashMap Text (c v) -> Maybe (c v)
forall k v. (Eq k, Hashable k) => k -> HashMap k v -> Maybe v
HM.lookup Text
k HashMap Text (c v)
hm

-- | List up all entries.
pMapToList :: F.Foldable c => PMap c v -> [(Text, v)]
pMapToList :: PMap c v -> [(Text, v)]
pMapToList (PMap HashMap Text (c v)
hm) = (Text, c v) -> [(Text, v)]
forall (t :: * -> *) a b. Foldable t => (a, t b) -> [(a, b)]
expandValues ((Text, c v) -> [(Text, v)]) -> [(Text, c v)] -> [(Text, v)]
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< HashMap Text (c v) -> [(Text, c v)]
forall k v. HashMap k v -> [(k, v)]
HM.toList HashMap Text (c v)
hm
  where
    expandValues :: (a, t b) -> [(a, b)]
expandValues (a
k, t b
cv) = (b -> (a, b)) -> [b] -> [(a, b)]
forall a b. (a -> b) -> [a] -> [b]
map ((,) a
k) ([b] -> [(a, b)]) -> [b] -> [(a, b)]
forall a b. (a -> b) -> a -> b
$ t b -> [b]
forall (t :: * -> *) a. Foldable t => t a -> [a]
F.toList t b
cv

-- | Make a 'PMap' from list of entries.
pMapFromList :: NonEmptyLike c => [(Text, v)] -> PMap c v
pMapFromList :: [(Text, v)] -> PMap c v
pMapFromList = ((Text, v) -> PMap c v -> PMap c v)
-> PMap c v -> [(Text, v)] -> PMap c v
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
F.foldr (Text, v) -> PMap c v -> PMap c v
forall (c :: * -> *) v.
NonEmptyLike c =>
(Text, v) -> PMap c v -> PMap c v
f PMap c v
forall a. Monoid a => a
mempty
  where
    f :: (Text, v) -> PMap c v -> PMap c v
f (Text
k, v
v) PMap c v
pm = Text -> v -> PMap c v -> PMap c v
forall (c :: * -> *) v.
NonEmptyLike c =>
Text -> v -> PMap c v -> PMap c v
pMapInsert Text
k v
v PMap c v
pm

-- | Lookup the first value for the key from 'PMap'.
lookup :: (PMapKey k, NonEmptyLike c) => k -> PMap c v -> Maybe v
lookup :: k -> PMap c v -> Maybe v
lookup k
k PMap c v
pm = [v] -> Maybe v
forall a. [a] -> Maybe a
listToMaybe ([v] -> Maybe v) -> [v] -> Maybe v
forall a b. (a -> b) -> a -> b
$ k -> PMap c v -> [v]
forall k (c :: * -> *) v.
(PMapKey k, NonEmptyLike c) =>
k -> PMap c v -> [v]
lookupList k
k PMap c v
pm

-- | 'MonadThrow' version of 'lookup'. If there is no value for the
-- key, it throws 'PMapNoSuchKey'.
lookupM :: (PMapKey k, NonEmptyLike c, MonadThrow m) => k -> PMap c v -> m v
lookupM :: k -> PMap c v -> m v
lookupM k
k PMap c v
pm = m v -> (v -> m v) -> Maybe v -> m v
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (PMapLookupException -> m v
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM (PMapLookupException -> m v) -> PMapLookupException -> m v
forall a b. (a -> b) -> a -> b
$ Text -> PMapLookupException
PMapNoSuchKey (Text -> PMapLookupException) -> Text -> PMapLookupException
forall a b. (a -> b) -> a -> b
$ k -> Text
forall k. PMapKey k => k -> Text
keyText k
k) v -> m v
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe v -> m v) -> Maybe v -> m v
forall a b. (a -> b) -> a -> b
$ k -> PMap c v -> Maybe v
forall k (c :: * -> *) v.
(PMapKey k, NonEmptyLike c) =>
k -> PMap c v -> Maybe v
lookup k
k PMap c v
pm

-- | Lookup the value and parse it into @a@.
lookupAs :: (PMapKey k, NonEmptyLike c, PMapValue k ~ a, FromGraphSON a)
         => k -> PMap c GValue -> Either PMapLookupException a
lookupAs :: k -> PMap c GValue -> Either PMapLookupException a
lookupAs k
k PMap c GValue
pm =
  case k -> PMap c GValue -> Maybe GValue
forall k (c :: * -> *) v.
(PMapKey k, NonEmptyLike c) =>
k -> PMap c v -> Maybe v
lookup k
k PMap c GValue
pm of
    Maybe GValue
Nothing -> PMapLookupException -> Either PMapLookupException a
forall a b. a -> Either a b
Left (PMapLookupException -> Either PMapLookupException a)
-> PMapLookupException -> Either PMapLookupException a
forall a b. (a -> b) -> a -> b
$ Text -> PMapLookupException
PMapNoSuchKey Text
kt
    Just GValue
gv -> (String -> Either PMapLookupException a)
-> (a -> Either PMapLookupException a)
-> Either String a
-> Either PMapLookupException a
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (PMapLookupException -> Either PMapLookupException a
forall a b. a -> Either a b
Left (PMapLookupException -> Either PMapLookupException a)
-> (String -> PMapLookupException)
-> String
-> Either PMapLookupException a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> String -> PMapLookupException
PMapParseError Text
kt) a -> Either PMapLookupException a
forall a b. b -> Either a b
Right (Either String a -> Either PMapLookupException a)
-> Either String a -> Either PMapLookupException a
forall a b. (a -> b) -> a -> b
$ GValue -> Either String a
forall a. FromGraphSON a => GValue -> Either String a
parseEither GValue
gv
  where
    kt :: Text
kt = k -> Text
forall k. PMapKey k => k -> Text
keyText k
k

-- | Similar to 'lookupAs', but this function converts a @null@ result
-- into 'Nothing'.
--
-- A @null@ result is either (1) the key @k@ is not found in the map,
-- or (2) the key is found, but the value is @null@.
lookupAs' :: (PMapKey k, NonEmptyLike c, PMapValue k ~ (Maybe a), FromGraphSON a)
          => k -> PMap c GValue -> Either PMapLookupException (Maybe a)
lookupAs' :: k -> PMap c GValue -> Either PMapLookupException (Maybe a)
lookupAs' k
k PMap c GValue
pm = (PMapLookupException -> Either PMapLookupException (Maybe a))
-> (Maybe a -> Either PMapLookupException (Maybe a))
-> Either PMapLookupException (Maybe a)
-> Either PMapLookupException (Maybe a)
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either PMapLookupException -> Either PMapLookupException (Maybe a)
forall a.
PMapLookupException -> Either PMapLookupException (Maybe a)
fromError Maybe a -> Either PMapLookupException (Maybe a)
forall a b. b -> Either a b
Right (Either PMapLookupException (Maybe a)
 -> Either PMapLookupException (Maybe a))
-> Either PMapLookupException (Maybe a)
-> Either PMapLookupException (Maybe a)
forall a b. (a -> b) -> a -> b
$ k -> PMap c GValue -> Either PMapLookupException (Maybe a)
forall k (c :: * -> *) a.
(PMapKey k, NonEmptyLike c, PMapValue k ~ a, FromGraphSON a) =>
k -> PMap c GValue -> Either PMapLookupException a
lookupAs k
k PMap c GValue
pm
  where
    fromError :: PMapLookupException -> Either PMapLookupException (Maybe a)
fromError (PMapNoSuchKey Text
_) = Maybe a -> Either PMapLookupException (Maybe a)
forall a b. b -> Either a b
Right Maybe a
forall a. Maybe a
Nothing
    fromError PMapLookupException
e = PMapLookupException -> Either PMapLookupException (Maybe a)
forall a b. a -> Either a b
Left PMapLookupException
e

-- | 'MonadThrow' version of 'lookupAs'.
lookupAsM :: (PMapKey k, NonEmptyLike c, PMapValue k ~ a, FromGraphSON a, MonadThrow m)
          => k -> PMap c GValue -> m a
lookupAsM :: k -> PMap c GValue -> m a
lookupAsM k
k PMap c GValue
pm = Either PMapLookupException a -> m a
forall (m :: * -> *) a.
MonadThrow m =>
Either PMapLookupException a -> m a
pMapToThrow (Either PMapLookupException a -> m a)
-> Either PMapLookupException a -> m a
forall a b. (a -> b) -> a -> b
$ k -> PMap c GValue -> Either PMapLookupException a
forall k (c :: * -> *) a.
(PMapKey k, NonEmptyLike c, PMapValue k ~ a, FromGraphSON a) =>
k -> PMap c GValue -> Either PMapLookupException a
lookupAs k
k PMap c GValue
pm

-- | Lookup all items for the key. If there is no item for the key, it
-- returns an empty list.
lookupList :: (PMapKey k, NonEmptyLike c) => k -> PMap c v -> [v]
lookupList :: k -> PMap c v -> [v]
lookupList k
k PMap c v
pm = Text -> PMap c v -> [v]
forall (c :: * -> *) v. NonEmptyLike c => Text -> PMap c v -> [v]
pMapLookup (k -> Text
forall k. PMapKey k => k -> Text
keyText k
k) PMap c v
pm

-- | Look up the values and parse them into @a@.
lookupListAs :: (PMapKey k, NonEmptyLike c, PMapValue k ~ a, FromGraphSON a)
             => k -> PMap c GValue -> Either PMapLookupException (NonEmpty a)
lookupListAs :: k -> PMap c GValue -> Either PMapLookupException (NonEmpty a)
lookupListAs k
k PMap c GValue
pm =
  case k -> PMap c GValue -> [GValue]
forall k (c :: * -> *) v.
(PMapKey k, NonEmptyLike c) =>
k -> PMap c v -> [v]
lookupList k
k PMap c GValue
pm of
    [] -> PMapLookupException -> Either PMapLookupException (NonEmpty a)
forall a b. a -> Either a b
Left (PMapLookupException -> Either PMapLookupException (NonEmpty a))
-> PMapLookupException -> Either PMapLookupException (NonEmpty a)
forall a b. (a -> b) -> a -> b
$ Text -> PMapLookupException
PMapNoSuchKey Text
kt
    (GValue
x : [GValue]
rest) -> (String -> Either PMapLookupException (NonEmpty a))
-> (NonEmpty a -> Either PMapLookupException (NonEmpty a))
-> Either String (NonEmpty a)
-> Either PMapLookupException (NonEmpty a)
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (PMapLookupException -> Either PMapLookupException (NonEmpty a)
forall a b. a -> Either a b
Left (PMapLookupException -> Either PMapLookupException (NonEmpty a))
-> (String -> PMapLookupException)
-> String
-> Either PMapLookupException (NonEmpty a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> String -> PMapLookupException
PMapParseError Text
kt) NonEmpty a -> Either PMapLookupException (NonEmpty a)
forall a b. b -> Either a b
Right (Either String (NonEmpty a)
 -> Either PMapLookupException (NonEmpty a))
-> Either String (NonEmpty a)
-> Either PMapLookupException (NonEmpty a)
forall a b. (a -> b) -> a -> b
$ (GValue -> Either String a)
-> NonEmpty GValue -> Either String (NonEmpty a)
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse GValue -> Either String a
forall a. FromGraphSON a => GValue -> Either String a
parseEither (GValue
x GValue -> [GValue] -> NonEmpty GValue
forall a. a -> [a] -> NonEmpty a
:| [GValue]
rest)
  where
    kt :: Text
kt = k -> Text
forall k. PMapKey k => k -> Text
keyText k
k

-- | Similar to 'lookupListAs', but this function accepts @null@
-- results.
--
-- If the key @k@ is not found in the map, it returns an empty
-- list. If the key @k@ is found and @null@s are included in the
-- values, they are obtained as 'Nothing'.
lookupListAs' :: (PMapKey k, NonEmptyLike c, PMapValue k ~ (Maybe a), FromGraphSON a)
              => k -> PMap c GValue -> Either PMapLookupException [Maybe a]
lookupListAs' :: k -> PMap c GValue -> Either PMapLookupException [Maybe a]
lookupListAs' k
k PMap c GValue
pm = (PMapLookupException -> Either PMapLookupException [Maybe a])
-> (NonEmpty (Maybe a) -> Either PMapLookupException [Maybe a])
-> Either PMapLookupException (NonEmpty (Maybe a))
-> Either PMapLookupException [Maybe a]
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either PMapLookupException -> Either PMapLookupException [Maybe a]
forall a. PMapLookupException -> Either PMapLookupException [a]
fromError ([Maybe a] -> Either PMapLookupException [Maybe a]
forall a b. b -> Either a b
Right ([Maybe a] -> Either PMapLookupException [Maybe a])
-> (NonEmpty (Maybe a) -> [Maybe a])
-> NonEmpty (Maybe a)
-> Either PMapLookupException [Maybe a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NonEmpty (Maybe a) -> [Maybe a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
F.toList) (Either PMapLookupException (NonEmpty (Maybe a))
 -> Either PMapLookupException [Maybe a])
-> Either PMapLookupException (NonEmpty (Maybe a))
-> Either PMapLookupException [Maybe a]
forall a b. (a -> b) -> a -> b
$ k
-> PMap c GValue -> Either PMapLookupException (NonEmpty (Maybe a))
forall k (c :: * -> *) a.
(PMapKey k, NonEmptyLike c, PMapValue k ~ a, FromGraphSON a) =>
k -> PMap c GValue -> Either PMapLookupException (NonEmpty a)
lookupListAs k
k PMap c GValue
pm
  where
    fromError :: PMapLookupException -> Either PMapLookupException [a]
fromError (PMapNoSuchKey Text
_) = [a] -> Either PMapLookupException [a]
forall a b. b -> Either a b
Right []
    fromError PMapLookupException
e = PMapLookupException -> Either PMapLookupException [a]
forall a b. a -> Either a b
Left PMapLookupException
e

-- | The single cardinality for 'PMap'. 'pMapInsert' method replaces
-- the old value. '<>' on 'PMap' prefers the items from the left
-- 'PMap'. 'pMapFromList' prefers the first item for each key.
--
-- @since 1.0.0.0
type Single = S.First

-- | The \"one or more\" cardinality for 'PMap'. 'pMapInsert' method
-- prepends the new value at the head. '<>' on 'PMap' appends the
-- right items to the tail of the left items. 'pMapFromList' preserves
-- the order of the items for each key.
--
-- @since 1.0.0.0
newtype Multi a = Multi (NonEmpty a)
              deriving (Int -> Multi a -> ShowS
[Multi a] -> ShowS
Multi a -> String
(Int -> Multi a -> ShowS)
-> (Multi a -> String) -> ([Multi a] -> ShowS) -> Show (Multi a)
forall a. Show a => Int -> Multi a -> ShowS
forall a. Show a => [Multi a] -> ShowS
forall a. Show a => Multi a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Multi a] -> ShowS
$cshowList :: forall a. Show a => [Multi a] -> ShowS
show :: Multi a -> String
$cshow :: forall a. Show a => Multi a -> String
showsPrec :: Int -> Multi a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> Multi a -> ShowS
Show,Multi a -> Multi a -> Bool
(Multi a -> Multi a -> Bool)
-> (Multi a -> Multi a -> Bool) -> Eq (Multi a)
forall a. Eq a => Multi a -> Multi a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Multi a -> Multi a -> Bool
$c/= :: forall a. Eq a => Multi a -> Multi a -> Bool
== :: Multi a -> Multi a -> Bool
$c== :: forall a. Eq a => Multi a -> Multi a -> Bool
Eq,Eq (Multi a)
Eq (Multi a)
-> (Multi a -> Multi a -> Ordering)
-> (Multi a -> Multi a -> Bool)
-> (Multi a -> Multi a -> Bool)
-> (Multi a -> Multi a -> Bool)
-> (Multi a -> Multi a -> Bool)
-> (Multi a -> Multi a -> Multi a)
-> (Multi a -> Multi a -> Multi a)
-> Ord (Multi a)
Multi a -> Multi a -> Bool
Multi a -> Multi a -> Ordering
Multi a -> Multi a -> Multi a
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall a. Ord a => Eq (Multi a)
forall a. Ord a => Multi a -> Multi a -> Bool
forall a. Ord a => Multi a -> Multi a -> Ordering
forall a. Ord a => Multi a -> Multi a -> Multi a
min :: Multi a -> Multi a -> Multi a
$cmin :: forall a. Ord a => Multi a -> Multi a -> Multi a
max :: Multi a -> Multi a -> Multi a
$cmax :: forall a. Ord a => Multi a -> Multi a -> Multi a
>= :: Multi a -> Multi a -> Bool
$c>= :: forall a. Ord a => Multi a -> Multi a -> Bool
> :: Multi a -> Multi a -> Bool
$c> :: forall a. Ord a => Multi a -> Multi a -> Bool
<= :: Multi a -> Multi a -> Bool
$c<= :: forall a. Ord a => Multi a -> Multi a -> Bool
< :: Multi a -> Multi a -> Bool
$c< :: forall a. Ord a => Multi a -> Multi a -> Bool
compare :: Multi a -> Multi a -> Ordering
$ccompare :: forall a. Ord a => Multi a -> Multi a -> Ordering
$cp1Ord :: forall a. Ord a => Eq (Multi a)
Ord,a -> Multi b -> Multi a
(a -> b) -> Multi a -> Multi b
(forall a b. (a -> b) -> Multi a -> Multi b)
-> (forall a b. a -> Multi b -> Multi a) -> Functor Multi
forall a b. a -> Multi b -> Multi a
forall a b. (a -> b) -> Multi a -> Multi b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: a -> Multi b -> Multi a
$c<$ :: forall a b. a -> Multi b -> Multi a
fmap :: (a -> b) -> Multi a -> Multi b
$cfmap :: forall a b. (a -> b) -> Multi a -> Multi b
Functor,b -> Multi a -> Multi a
NonEmpty (Multi a) -> Multi a
Multi a -> Multi a -> Multi a
(Multi a -> Multi a -> Multi a)
-> (NonEmpty (Multi a) -> Multi a)
-> (forall b. Integral b => b -> Multi a -> Multi a)
-> Semigroup (Multi a)
forall b. Integral b => b -> Multi a -> Multi a
forall a. NonEmpty (Multi a) -> Multi a
forall a. Multi a -> Multi a -> Multi a
forall a.
(a -> a -> a)
-> (NonEmpty a -> a)
-> (forall b. Integral b => b -> a -> a)
-> Semigroup a
forall a b. Integral b => b -> Multi a -> Multi a
stimes :: b -> Multi a -> Multi a
$cstimes :: forall a b. Integral b => b -> Multi a -> Multi a
sconcat :: NonEmpty (Multi a) -> Multi a
$csconcat :: forall a. NonEmpty (Multi a) -> Multi a
<> :: Multi a -> Multi a -> Multi a
$c<> :: forall a. Multi a -> Multi a -> Multi a
Semigroup,a -> Multi a -> Bool
Multi m -> m
Multi a -> [a]
Multi a -> Bool
Multi a -> Int
Multi a -> a
Multi a -> a
Multi a -> a
Multi a -> a
(a -> m) -> Multi a -> m
(a -> m) -> Multi a -> m
(a -> b -> b) -> b -> Multi a -> b
(a -> b -> b) -> b -> Multi a -> b
(b -> a -> b) -> b -> Multi a -> b
(b -> a -> b) -> b -> Multi a -> b
(a -> a -> a) -> Multi a -> a
(a -> a -> a) -> Multi a -> a
(forall m. Monoid m => Multi m -> m)
-> (forall m a. Monoid m => (a -> m) -> Multi a -> m)
-> (forall m a. Monoid m => (a -> m) -> Multi a -> m)
-> (forall a b. (a -> b -> b) -> b -> Multi a -> b)
-> (forall a b. (a -> b -> b) -> b -> Multi a -> b)
-> (forall b a. (b -> a -> b) -> b -> Multi a -> b)
-> (forall b a. (b -> a -> b) -> b -> Multi a -> b)
-> (forall a. (a -> a -> a) -> Multi a -> a)
-> (forall a. (a -> a -> a) -> Multi a -> a)
-> (forall a. Multi a -> [a])
-> (forall a. Multi a -> Bool)
-> (forall a. Multi a -> Int)
-> (forall a. Eq a => a -> Multi a -> Bool)
-> (forall a. Ord a => Multi a -> a)
-> (forall a. Ord a => Multi a -> a)
-> (forall a. Num a => Multi a -> a)
-> (forall a. Num a => Multi a -> a)
-> Foldable Multi
forall a. Eq a => a -> Multi a -> Bool
forall a. Num a => Multi a -> a
forall a. Ord a => Multi a -> a
forall m. Monoid m => Multi m -> m
forall a. Multi a -> Bool
forall a. Multi a -> Int
forall a. Multi a -> [a]
forall a. (a -> a -> a) -> Multi a -> a
forall m a. Monoid m => (a -> m) -> Multi a -> m
forall b a. (b -> a -> b) -> b -> Multi a -> b
forall a b. (a -> b -> b) -> b -> Multi a -> b
forall (t :: * -> *).
(forall m. Monoid m => t m -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. t a -> [a])
-> (forall a. t a -> Bool)
-> (forall a. t a -> Int)
-> (forall a. Eq a => a -> t a -> Bool)
-> (forall a. Ord a => t a -> a)
-> (forall a. Ord a => t a -> a)
-> (forall a. Num a => t a -> a)
-> (forall a. Num a => t a -> a)
-> Foldable t
product :: Multi a -> a
$cproduct :: forall a. Num a => Multi a -> a
sum :: Multi a -> a
$csum :: forall a. Num a => Multi a -> a
minimum :: Multi a -> a
$cminimum :: forall a. Ord a => Multi a -> a
maximum :: Multi a -> a
$cmaximum :: forall a. Ord a => Multi a -> a
elem :: a -> Multi a -> Bool
$celem :: forall a. Eq a => a -> Multi a -> Bool
length :: Multi a -> Int
$clength :: forall a. Multi a -> Int
null :: Multi a -> Bool
$cnull :: forall a. Multi a -> Bool
toList :: Multi a -> [a]
$ctoList :: forall a. Multi a -> [a]
foldl1 :: (a -> a -> a) -> Multi a -> a
$cfoldl1 :: forall a. (a -> a -> a) -> Multi a -> a
foldr1 :: (a -> a -> a) -> Multi a -> a
$cfoldr1 :: forall a. (a -> a -> a) -> Multi a -> a
foldl' :: (b -> a -> b) -> b -> Multi a -> b
$cfoldl' :: forall b a. (b -> a -> b) -> b -> Multi a -> b
foldl :: (b -> a -> b) -> b -> Multi a -> b
$cfoldl :: forall b a. (b -> a -> b) -> b -> Multi a -> b
foldr' :: (a -> b -> b) -> b -> Multi a -> b
$cfoldr' :: forall a b. (a -> b -> b) -> b -> Multi a -> b
foldr :: (a -> b -> b) -> b -> Multi a -> b
$cfoldr :: forall a b. (a -> b -> b) -> b -> Multi a -> b
foldMap' :: (a -> m) -> Multi a -> m
$cfoldMap' :: forall m a. Monoid m => (a -> m) -> Multi a -> m
foldMap :: (a -> m) -> Multi a -> m
$cfoldMap :: forall m a. Monoid m => (a -> m) -> Multi a -> m
fold :: Multi m -> m
$cfold :: forall m. Monoid m => Multi m -> m
Foldable,Functor Multi
Foldable Multi
Functor Multi
-> Foldable Multi
-> (forall (f :: * -> *) a b.
    Applicative f =>
    (a -> f b) -> Multi a -> f (Multi b))
-> (forall (f :: * -> *) a.
    Applicative f =>
    Multi (f a) -> f (Multi a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> Multi a -> m (Multi b))
-> (forall (m :: * -> *) a. Monad m => Multi (m a) -> m (Multi a))
-> Traversable Multi
(a -> f b) -> Multi a -> f (Multi b)
forall (t :: * -> *).
Functor t
-> Foldable t
-> (forall (f :: * -> *) a b.
    Applicative f =>
    (a -> f b) -> t a -> f (t b))
-> (forall (f :: * -> *) a. Applicative f => t (f a) -> f (t a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> t a -> m (t b))
-> (forall (m :: * -> *) a. Monad m => t (m a) -> m (t a))
-> Traversable t
forall (m :: * -> *) a. Monad m => Multi (m a) -> m (Multi a)
forall (f :: * -> *) a. Applicative f => Multi (f a) -> f (Multi a)
forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Multi a -> m (Multi b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Multi a -> f (Multi b)
sequence :: Multi (m a) -> m (Multi a)
$csequence :: forall (m :: * -> *) a. Monad m => Multi (m a) -> m (Multi a)
mapM :: (a -> m b) -> Multi a -> m (Multi b)
$cmapM :: forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Multi a -> m (Multi b)
sequenceA :: Multi (f a) -> f (Multi a)
$csequenceA :: forall (f :: * -> *) a. Applicative f => Multi (f a) -> f (Multi a)
traverse :: (a -> f b) -> Multi a -> f (Multi b)
$ctraverse :: forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Multi a -> f (Multi b)
$cp2Traversable :: Foldable Multi
$cp1Traversable :: Functor Multi
Traversable,Foldable Multi
a -> Multi a
Foldable Multi
-> (forall a. a -> Multi a)
-> (forall a. Multi a -> Multi a -> Multi a)
-> (forall a. Multi a -> NonEmpty a)
-> NonEmptyLike Multi
Multi a -> Multi a -> Multi a
Multi a -> NonEmpty a
forall a. a -> Multi a
forall a. Multi a -> NonEmpty a
forall a. Multi a -> Multi a -> Multi a
forall (t :: * -> *).
Foldable t
-> (forall a. a -> t a)
-> (forall a. t a -> t a -> t a)
-> (forall a. t a -> NonEmpty a)
-> NonEmptyLike t
toNonEmpty :: Multi a -> NonEmpty a
$ctoNonEmpty :: forall a. Multi a -> NonEmpty a
append :: Multi a -> Multi a -> Multi a
$cappend :: forall a. Multi a -> Multi a -> Multi a
singleton :: a -> Multi a
$csingleton :: forall a. a -> Multi a
$cp1NonEmptyLike :: Foldable Multi
NonEmptyLike,GValue -> Parser (Multi a)
(GValue -> Parser (Multi a)) -> FromGraphSON (Multi a)
forall a. FromGraphSON a => GValue -> Parser (Multi a)
forall a. (GValue -> Parser a) -> FromGraphSON a
parseGraphSON :: GValue -> Parser (Multi a)
$cparseGraphSON :: forall a. FromGraphSON a => GValue -> Parser (Multi a)
FromGraphSON)

-- | A typed key for 'PMap'.
--
-- @since 1.0.0.0
class PMapKey k where
  -- | Type of the value associated with the key.
  type PMapValue k :: *

  -- | 'Text' representation of the key.
  keyText :: k -> Text

-- | For simple 'Text', the 'GValue' is returned without being parsed.
instance PMapKey Text where
  type PMapValue Text = GValue
  keyText :: Text -> Text
keyText = Text -> Text
forall a. a -> a
id

-- | An 'Exception' raised when looking up values from 'PMap'.
--
-- @since 1.0.0.0
data PMapLookupException =
    PMapNoSuchKey Text
  -- ^ The 'PMap' doesn't have the given key.
  | PMapParseError Text String
  -- ^ Failed to parse the value into the type that the 'PMapKey'
  -- indicates. The 'Text' is the key, and the 'String' is the error
  -- message.
  deriving (Int -> PMapLookupException -> ShowS
[PMapLookupException] -> ShowS
PMapLookupException -> String
(Int -> PMapLookupException -> ShowS)
-> (PMapLookupException -> String)
-> ([PMapLookupException] -> ShowS)
-> Show PMapLookupException
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [PMapLookupException] -> ShowS
$cshowList :: [PMapLookupException] -> ShowS
show :: PMapLookupException -> String
$cshow :: PMapLookupException -> String
showsPrec :: Int -> PMapLookupException -> ShowS
$cshowsPrec :: Int -> PMapLookupException -> ShowS
Show,PMapLookupException -> PMapLookupException -> Bool
(PMapLookupException -> PMapLookupException -> Bool)
-> (PMapLookupException -> PMapLookupException -> Bool)
-> Eq PMapLookupException
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: PMapLookupException -> PMapLookupException -> Bool
$c/= :: PMapLookupException -> PMapLookupException -> Bool
== :: PMapLookupException -> PMapLookupException -> Bool
$c== :: PMapLookupException -> PMapLookupException -> Bool
Eq,Eq PMapLookupException
Eq PMapLookupException
-> (PMapLookupException -> PMapLookupException -> Ordering)
-> (PMapLookupException -> PMapLookupException -> Bool)
-> (PMapLookupException -> PMapLookupException -> Bool)
-> (PMapLookupException -> PMapLookupException -> Bool)
-> (PMapLookupException -> PMapLookupException -> Bool)
-> (PMapLookupException
    -> PMapLookupException -> PMapLookupException)
-> (PMapLookupException
    -> PMapLookupException -> PMapLookupException)
-> Ord PMapLookupException
PMapLookupException -> PMapLookupException -> Bool
PMapLookupException -> PMapLookupException -> Ordering
PMapLookupException -> PMapLookupException -> PMapLookupException
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: PMapLookupException -> PMapLookupException -> PMapLookupException
$cmin :: PMapLookupException -> PMapLookupException -> PMapLookupException
max :: PMapLookupException -> PMapLookupException -> PMapLookupException
$cmax :: PMapLookupException -> PMapLookupException -> PMapLookupException
>= :: PMapLookupException -> PMapLookupException -> Bool
$c>= :: PMapLookupException -> PMapLookupException -> Bool
> :: PMapLookupException -> PMapLookupException -> Bool
$c> :: PMapLookupException -> PMapLookupException -> Bool
<= :: PMapLookupException -> PMapLookupException -> Bool
$c<= :: PMapLookupException -> PMapLookupException -> Bool
< :: PMapLookupException -> PMapLookupException -> Bool
$c< :: PMapLookupException -> PMapLookupException -> Bool
compare :: PMapLookupException -> PMapLookupException -> Ordering
$ccompare :: PMapLookupException -> PMapLookupException -> Ordering
$cp1Ord :: Eq PMapLookupException
Ord)

instance Exception PMapLookupException

-- | Make a human-readable description on 'PMapLookupException'.
pMapDecribeError :: PMapLookupException -> String
pMapDecribeError :: PMapLookupException -> String
pMapDecribeError (PMapNoSuchKey Text
k) = String
"Property '" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Text -> String
unpack Text
k String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"' does not exist."
pMapDecribeError (PMapParseError Text
k String
pe) = String
"Parse error of property '" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Text -> String
unpack Text
k String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"': " String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
pe

-- | Convert the lookup result into a 'MonadThrow'. It throws
-- 'PMapLookupException'.
pMapToThrow :: MonadThrow m => Either PMapLookupException a -> m a
pMapToThrow :: Either PMapLookupException a -> m a
pMapToThrow (Left PMapLookupException
e) = PMapLookupException -> m a
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM PMapLookupException
e
pMapToThrow (Right a
a) = a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return a
a

-- | Convert the lookup result into a 'MonadFail'. It fails with the
-- description returned by 'pMapDecribeError'.
pMapToFail :: MonadFail m => Either PMapLookupException a -> m a
pMapToFail :: Either PMapLookupException a -> m a
pMapToFail (Left PMapLookupException
e) = String -> m a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> m a) -> String -> m a
forall a b. (a -> b) -> a -> b
$ PMapLookupException -> String
pMapDecribeError PMapLookupException
e
pMapToFail (Right a
a) = a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return a
a