openapi3-3.2.5: OpenAPI 3.0 data model
MaintainerNickolay Kudasov <nickolay@getshoptv.com>
Stabilityexperimental
Safe HaskellNone
LanguageHaskell2010

Data.HashMap.Strict.InsOrd.Compat

Description

Compatibility wrapper around insert-ordered-containers to mitigate the breaking changes introduced in insert-ordered-containers-0.3.0: https://github.com/erikd/insert-ordered-containers/pull/8.

That change fixed Eq and Aeson instances in the upstream package, but it is a behavioral break for swagger2 where we need stable Swagger Schema generation and JSON object-like encoding.

This module keeps the old swagger2 expectations:

  • InsOrdHashMap values are encoded as JSON objects (not arrays of key/value tuples), so field names remain first-class object keys.
  • Equality intentionally ignores insertion order (compares as plain hash maps), which matches how many tests currently assert JSON equality.

Simple encoding examples:

>>> import Data.Aeson (encode, eitherDecode)
>>> import qualified Data.ByteString.Lazy.Char8 as BSL8
>>> import qualified Data.HashMap.Strict as HM
>>> import qualified Data.HashMap.Strict.InsOrd.Compat as IOHM
>>> let decodeIOHM s = either error id (eitherDecode (BSL8.pack s) :: Either String (IOHM.InsOrdHashMap String Int))

A regular hash map has no insertion order guarantee:

>>> encode (HM.fromList [("a", 1 :: Int), ("b", 2)])
"{\"a\":1,\"b\":2}"
>>> encode (HM.fromList [("b", 1 :: Int), ("a", 2)])
"{\"a\":2,\"b\":1}"

Our compat InsOrdHashMap encodes to a JSON object as well, but preserves insertion order:

>>> encode (IOHM.fromList [("a", 1 :: Int), ("b", 2)])
"{\"a\":1,\"b\":2}"
>>> encode (IOHM.fromList [("b", 1 :: Int), ("a", 2)])
"{\"b\":1,\"a\":2}"

Round-tripping through decode/encode demonstrates the caveat: encoding preserves insertion order, but decoded object key order is not guaranteed.

>>> encode (decodeIOHM "{\"a\":1,\"b\":2}")
"{\"a\":1,\"b\":2}"
>>> encode (decodeIOHM "{\"b\":1,\"a\":2}")
"{\"a\":2,\"b\":1}"

This object encoding is what swagger2 wants for generated Swagger definitions/properties because it keeps emitted schemas easy to consume and stable in practice.

Important caveat: decoding cannot be fully stable with respect to insertion order due to aeson limitations. In particular, object parsing goes through structures that do not preserve all ordering guarantees end-to-end. We accept this trade-off for now because the primary requirement is deterministic encoding for generated Swagger Schema artifacts.

Many tests rely on aesonQQ-style JSON equality, where semantic object equality matters more than insertion order. Comparing via plain hash maps makes those tests robust under benign key-order variation. This is a weaker notion of equality and hopefully will be revisited later.

Synopsis

Documentation

data InsOrdHashMap k v Source #

Instances

Instances details
(Eq k, Hashable k) => FoldableWithIndex k (InsOrdHashMap k) Source # 
Instance details

Defined in Data.HashMap.Strict.InsOrd.Compat

Methods

ifoldMap :: Monoid m => (k -> a -> m) -> InsOrdHashMap k a -> m #

ifoldMap' :: Monoid m => (k -> a -> m) -> InsOrdHashMap k a -> m #

ifoldr :: (k -> a -> b -> b) -> b -> InsOrdHashMap k a -> b #

ifoldl :: (k -> b -> a -> b) -> b -> InsOrdHashMap k a -> b #

ifoldr' :: (k -> a -> b -> b) -> b -> InsOrdHashMap k a -> b #

ifoldl' :: (k -> b -> a -> b) -> b -> InsOrdHashMap k a -> b #

(Eq k, Hashable k) => FunctorWithIndex k (InsOrdHashMap k) Source # 
Instance details

Defined in Data.HashMap.Strict.InsOrd.Compat

Methods

imap :: (k -> a -> b) -> InsOrdHashMap k a -> InsOrdHashMap k b #

(Eq k, Hashable k) => TraversableWithIndex k (InsOrdHashMap k) Source # 
Instance details

Defined in Data.HashMap.Strict.InsOrd.Compat

Methods

itraverse :: Applicative f => (k -> a -> f b) -> InsOrdHashMap k a -> f (InsOrdHashMap k b) #

HasCallbacks Components (Definitions Callback) Source # 
Instance details

Defined in Data.OpenApi.Lens

HasExamples Components (Definitions Example) Source # 
Instance details

Defined in Data.OpenApi.Lens

HasHeaders Components (Definitions Header) Source # 
Instance details

Defined in Data.OpenApi.Lens

HasLinks Components (Definitions Link) Source # 
Instance details

Defined in Data.OpenApi.Lens

HasParameters Components (Definitions Param) Source # 
Instance details

Defined in Data.OpenApi.Lens

HasRequestBodies Components (Definitions RequestBody) Source # 
Instance details

Defined in Data.OpenApi.Lens

HasResponses Components (Definitions Response) Source # 
Instance details

Defined in Data.OpenApi.Lens

HasSchemas Components (Definitions Schema) Source # 
Instance details

Defined in Data.OpenApi.Lens

HasCallbacks Operation (InsOrdHashMap Text (Referenced Callback)) Source # 
Instance details

Defined in Data.OpenApi.Lens

HasContent RequestBody (InsOrdHashMap MediaType MediaTypeObject) Source # 
Instance details

Defined in Data.OpenApi.Lens

HasContent Response (InsOrdHashMap MediaType MediaTypeObject) Source # 
Instance details

Defined in Data.OpenApi.Lens

HasEncoding MediaTypeObject (InsOrdHashMap Text Encoding) Source # 
Instance details

Defined in Data.OpenApi.Lens

HasExamples Header (InsOrdHashMap Text (Referenced Example)) Source # 
Instance details

Defined in Data.OpenApi.Lens

HasExamples MediaTypeObject (InsOrdHashMap Text (Referenced Example)) Source # 
Instance details

Defined in Data.OpenApi.Lens

HasExamples Param (InsOrdHashMap Text (Referenced Example)) Source # 
Instance details

Defined in Data.OpenApi.Lens

HasHeaders Encoding (InsOrdHashMap Text (Referenced Header)) Source # 
Instance details

Defined in Data.OpenApi.Lens

HasHeaders Response (InsOrdHashMap HeaderName (Referenced Header)) Source # 
Instance details

Defined in Data.OpenApi.Lens

HasLinks Response (InsOrdHashMap Text (Referenced Link)) Source # 
Instance details

Defined in Data.OpenApi.Lens

HasMapping Discriminator (InsOrdHashMap Text Text) Source # 
Instance details

Defined in Data.OpenApi.Lens

HasParameters Link (InsOrdHashMap Text ExpressionOrValue) Source # 
Instance details

Defined in Data.OpenApi.Lens

HasPaths OpenApi (InsOrdHashMap FilePath PathItem) Source # 
Instance details

Defined in Data.OpenApi.Lens

HasProperties Schema (InsOrdHashMap Text (Referenced Schema)) Source # 
Instance details

Defined in Data.OpenApi.Lens

HasResponses Responses (InsOrdHashMap HttpStatusCode (Referenced Response)) Source # 
Instance details

Defined in Data.OpenApi.Lens

HasVariables Server (InsOrdHashMap Text ServerVariable) Source # 
Instance details

Defined in Data.OpenApi.Lens

(Eq k, Hashable k, FromJSONKey k) => FromJSON1 (InsOrdHashMap k) Source # 
Instance details

Defined in Data.HashMap.Strict.InsOrd.Compat

Methods

liftParseJSON :: Maybe a -> (Value -> Parser a) -> (Value -> Parser [a]) -> Value -> Parser (InsOrdHashMap k a) #

liftParseJSONList :: Maybe a -> (Value -> Parser a) -> (Value -> Parser [a]) -> Value -> Parser [InsOrdHashMap k a] #

liftOmittedField :: Maybe a -> Maybe (InsOrdHashMap k a) #

ToJSONKey k => ToJSON1 (InsOrdHashMap k) Source # 
Instance details

Defined in Data.HashMap.Strict.InsOrd.Compat

Methods

liftToJSON :: (a -> Bool) -> (a -> Value) -> ([a] -> Value) -> InsOrdHashMap k a -> Value #

liftToJSONList :: (a -> Bool) -> (a -> Value) -> ([a] -> Value) -> [InsOrdHashMap k a] -> Value #

liftToEncoding :: (a -> Bool) -> (a -> Encoding) -> ([a] -> Encoding) -> InsOrdHashMap k a -> Encoding #

liftToEncodingList :: (a -> Bool) -> (a -> Encoding) -> ([a] -> Encoding) -> [InsOrdHashMap k a] -> Encoding #

liftOmitField :: (a -> Bool) -> InsOrdHashMap k a -> Bool #

Foldable (InsOrdHashMap k) Source # 
Instance details

Defined in Data.HashMap.Strict.InsOrd.Compat

Methods

fold :: Monoid m => InsOrdHashMap k m -> m #

foldMap :: Monoid m => (a -> m) -> InsOrdHashMap k a -> m #

foldMap' :: Monoid m => (a -> m) -> InsOrdHashMap k a -> m #

foldr :: (a -> b -> b) -> b -> InsOrdHashMap k a -> b #

foldr' :: (a -> b -> b) -> b -> InsOrdHashMap k a -> b #

foldl :: (b -> a -> b) -> b -> InsOrdHashMap k a -> b #

foldl' :: (b -> a -> b) -> b -> InsOrdHashMap k a -> b #

foldr1 :: (a -> a -> a) -> InsOrdHashMap k a -> a #

foldl1 :: (a -> a -> a) -> InsOrdHashMap k a -> a #

toList :: InsOrdHashMap k a -> [a] #

null :: InsOrdHashMap k a -> Bool #

length :: InsOrdHashMap k a -> Int #

elem :: Eq a => a -> InsOrdHashMap k a -> Bool #

maximum :: Ord a => InsOrdHashMap k a -> a #

minimum :: Ord a => InsOrdHashMap k a -> a #

sum :: Num a => InsOrdHashMap k a -> a #

product :: Num a => InsOrdHashMap k a -> a #

Traversable (InsOrdHashMap k) Source # 
Instance details

Defined in Data.HashMap.Strict.InsOrd.Compat

Methods

traverse :: Applicative f => (a -> f b) -> InsOrdHashMap k a -> f (InsOrdHashMap k b) #

sequenceA :: Applicative f => InsOrdHashMap k (f a) -> f (InsOrdHashMap k a) #

mapM :: Monad m => (a -> m b) -> InsOrdHashMap k a -> m (InsOrdHashMap k b) #

sequence :: Monad m => InsOrdHashMap k (m a) -> m (InsOrdHashMap k a) #

Functor (InsOrdHashMap k) Source # 
Instance details

Defined in Data.HashMap.Strict.InsOrd.Compat

Methods

fmap :: (a -> b) -> InsOrdHashMap k a -> InsOrdHashMap k b #

(<$) :: a -> InsOrdHashMap k b -> InsOrdHashMap k a #

(Eq k, Hashable k, FromJSONKey k, FromJSON v) => FromJSON (InsOrdHashMap k v) Source # 
Instance details

Defined in Data.HashMap.Strict.InsOrd.Compat

(ToJSONKey k, ToJSON v) => ToJSON (InsOrdHashMap k v) Source # 
Instance details

Defined in Data.HashMap.Strict.InsOrd.Compat

(Data k, Data v, Hashable k) => Data (InsOrdHashMap k v) Source # 
Instance details

Defined in Data.HashMap.Strict.InsOrd.Compat

Methods

gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> InsOrdHashMap k v -> c (InsOrdHashMap k v) #

gunfold :: (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c (InsOrdHashMap k v) #

toConstr :: InsOrdHashMap k v -> Constr #

dataTypeOf :: InsOrdHashMap k v -> DataType #

dataCast1 :: Typeable t => (forall d. Data d => c (t d)) -> Maybe (c (InsOrdHashMap k v)) #

dataCast2 :: Typeable t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c (InsOrdHashMap k v)) #

gmapT :: (forall b. Data b => b -> b) -> InsOrdHashMap k v -> InsOrdHashMap k v #

gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> InsOrdHashMap k v -> r #

gmapQr :: forall r r'. (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> InsOrdHashMap k v -> r #

gmapQ :: (forall d. Data d => d -> u) -> InsOrdHashMap k v -> [u] #

gmapQi :: Int -> (forall d. Data d => d -> u) -> InsOrdHashMap k v -> u #

gmapM :: Monad m => (forall d. Data d => d -> m d) -> InsOrdHashMap k v -> m (InsOrdHashMap k v) #

gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> InsOrdHashMap k v -> m (InsOrdHashMap k v) #

gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> InsOrdHashMap k v -> m (InsOrdHashMap k v) #

Hashable k => Monoid (InsOrdHashMap k v) Source # 
Instance details

Defined in Data.HashMap.Strict.InsOrd.Compat

Hashable k => Semigroup (InsOrdHashMap k v) Source # 
Instance details

Defined in Data.HashMap.Strict.InsOrd.Compat

(Eq k, Hashable k) => IsList (InsOrdHashMap k v) Source # 
Instance details

Defined in Data.HashMap.Strict.InsOrd.Compat

Associated Types

type Item (InsOrdHashMap k v) 
Instance details

Defined in Data.HashMap.Strict.InsOrd.Compat

(Hashable k, Read k, Read v) => Read (InsOrdHashMap k v) Source # 
Instance details

Defined in Data.HashMap.Strict.InsOrd.Compat

(Show k, Show v) => Show (InsOrdHashMap k v) Source # 
Instance details

Defined in Data.HashMap.Strict.InsOrd.Compat

(Eq k, Eq v) => Eq (InsOrdHashMap k v) Source # 
Instance details

Defined in Data.HashMap.Strict.InsOrd.Compat

Methods

(==) :: InsOrdHashMap k v -> InsOrdHashMap k v -> Bool #

(/=) :: InsOrdHashMap k v -> InsOrdHashMap k v -> Bool #

(Eq k, Hashable k) => At (InsOrdHashMap k a) Source # 
Instance details

Defined in Data.HashMap.Strict.InsOrd.Compat

Methods

at :: Index (InsOrdHashMap k a) -> Lens' (InsOrdHashMap k a) (Maybe (IxValue (InsOrdHashMap k a))) #

(Eq k, Hashable k) => Ixed (InsOrdHashMap k v) Source # 
Instance details

Defined in Data.HashMap.Strict.InsOrd.Compat

AesonDefaultValue (InsOrdHashMap k v) Source # 
Instance details

Defined in Data.OpenApi.Internal.AesonUtils

SwaggerMonoid (InsOrdHashMap FilePath PathItem) Source # 
Instance details

Defined in Data.OpenApi.Internal

(Eq k, Hashable k) => SwaggerMonoid (InsOrdHashMap k v) Source # 
Instance details

Defined in Data.OpenApi.Internal.Utils

(Eq k, Hashable k) => At (InsOrdHashMap k a) Source # 
Instance details

Defined in Data.HashMap.Strict.InsOrd.Compat

Methods

at :: Index (InsOrdHashMap k a) -> Lens' (InsOrdHashMap k a) (Maybe (IxValue (InsOrdHashMap k a))) #

(Eq k, Hashable k) => Ixed (InsOrdHashMap k v) Source # 
Instance details

Defined in Data.HashMap.Strict.InsOrd.Compat

Associated Types

type IxKind (InsOrdHashMap k v) 
Instance details

Defined in Data.HashMap.Strict.InsOrd.Compat

type Item (InsOrdHashMap k v) Source # 
Instance details

Defined in Data.HashMap.Strict.InsOrd.Compat

type Index (InsOrdHashMap k v) Source # 
Instance details

Defined in Data.HashMap.Strict.InsOrd.Compat

type Index (InsOrdHashMap k v) = k
type IxValue (InsOrdHashMap k v) Source # 
Instance details

Defined in Data.HashMap.Strict.InsOrd.Compat

type IxValue (InsOrdHashMap k v) = v
type Index (InsOrdHashMap k v) Source # 
Instance details

Defined in Data.HashMap.Strict.InsOrd.Compat

type Index (InsOrdHashMap k v) = k
type IxKind (InsOrdHashMap k v) Source # 
Instance details

Defined in Data.HashMap.Strict.InsOrd.Compat

type IxValue (InsOrdHashMap k v) Source # 
Instance details

Defined in Data.HashMap.Strict.InsOrd.Compat

type IxValue (InsOrdHashMap k v) = v

Construction

singleton :: Hashable k => k -> v -> InsOrdHashMap k v Source #

Basic interface

lookup :: Hashable k => k -> InsOrdHashMap k v -> Maybe v Source #

lookupDefault :: Hashable k => v -> k -> InsOrdHashMap k v -> v Source #

insert :: Hashable k => k -> v -> InsOrdHashMap k v -> InsOrdHashMap k v Source #

insertWith :: Hashable k => (v -> v -> v) -> k -> v -> InsOrdHashMap k v -> InsOrdHashMap k v Source #

adjust :: Hashable k => (v -> v) -> k -> InsOrdHashMap k v -> InsOrdHashMap k v Source #

update :: Hashable k => (v -> Maybe v) -> k -> InsOrdHashMap k v -> InsOrdHashMap k v Source #

alter :: Hashable k => (Maybe v -> Maybe v) -> k -> InsOrdHashMap k v -> InsOrdHashMap k v Source #

Combine

unionWith :: Hashable k => (v -> v -> v) -> InsOrdHashMap k v -> InsOrdHashMap k v -> InsOrdHashMap k v Source #

unionWithKey :: Hashable k => (k -> v -> v -> v) -> InsOrdHashMap k v -> InsOrdHashMap k v -> InsOrdHashMap k v Source #

Transformations

map :: (v -> v) -> InsOrdHashMap k v -> InsOrdHashMap k v Source #

mapKeys :: Hashable k => (k -> k) -> InsOrdHashMap k v -> InsOrdHashMap k v Source #

traverseKeys :: (Applicative f, Hashable k) => (k -> f k) -> InsOrdHashMap k v -> f (InsOrdHashMap k v) Source #

mapWithKey :: (k -> v1 -> v2) -> InsOrdHashMap k v1 -> InsOrdHashMap k v2 Source #

traverseWithKey :: (Applicative f, Hashable k) => (k -> v1 -> f v2) -> InsOrdHashMap k v1 -> f (InsOrdHashMap k v2) Source #

Unordered

unorderedTraverse :: (Applicative f, Hashable k) => (v -> f v) -> InsOrdHashMap k v -> f (InsOrdHashMap k v) Source #

unorderedTraverseWithKey :: (Applicative f, Hashable k) => (k -> v -> f v) -> InsOrdHashMap k v -> f (InsOrdHashMap k v) Source #

Difference and intersection

intersectionWith :: Hashable k => (v -> v -> v) -> InsOrdHashMap k v -> InsOrdHashMap k v -> InsOrdHashMap k v Source #

intersectionWithKey :: Hashable k => (k -> v -> v -> v) -> InsOrdHashMap k v -> InsOrdHashMap k v -> InsOrdHashMap k v Source #

Folds

foldl' :: (a -> v -> a) -> a -> InsOrdHashMap k v -> a Source #

foldlWithKey' :: (a -> k -> v -> a) -> a -> InsOrdHashMap k v -> a Source #

foldr :: Foldable t => (a -> b -> b) -> b -> t a -> b #

Right-associative fold of a structure, lazy in the accumulator.

In the case of lists, foldr, when applied to a binary operator, a starting value (typically the right-identity of the operator), and a list, reduces the list using the binary operator, from right to left:

foldr f z [x1, x2, ..., xn] == x1 `f` (x2 `f` ... (xn `f` z)...)

Note that since the head of the resulting expression is produced by an application of the operator to the first element of the list, given an operator lazy in its right argument, foldr can produce a terminating expression from an unbounded list.

For a general Foldable structure this should be semantically identical to,

foldr f z = foldr f z . toList

Examples

Expand

Basic usage:

>>> foldr (||) False [False, True, False]
True
>>> foldr (||) False []
False
>>> foldr (\c acc -> acc ++ [c]) "foo" ['a', 'b', 'c', 'd']
"foodcba"
Infinite structures

⚠️ Applying foldr to infinite structures usually doesn't terminate.

It may still terminate under one of the following conditions:

  • the folding function is short-circuiting
  • the folding function is lazy on its second argument
Short-circuiting

(||) short-circuits on True values, so the following terminates because there is a True value finitely far from the left side:

>>> foldr (||) False (True : repeat False)
True

But the following doesn't terminate:

>>> foldr (||) False (repeat False ++ [True])
* Hangs forever *
Laziness in the second argument

Applying foldr to infinite structures terminates when the operator is lazy in its second argument (the initial accumulator is never used in this case, and so could be left undefined, but [] is more clear):

>>> take 5 $ foldr (\i acc -> i : fmap (+3) acc) [] (repeat 1)
[1,4,7,10,13]

foldrWithKey :: (k -> v -> a -> a) -> a -> InsOrdHashMap k v -> a Source #

foldMapWithKey :: Monoid m => (k -> v -> m) -> InsOrdHashMap k v -> m Source #

Unordered

unorderedFoldMap :: Monoid m => (v -> m) -> InsOrdHashMap k v -> m Source #

unorderedFoldMapWithKey :: Monoid m => (k -> v -> m) -> InsOrdHashMap k v -> m Source #

Filter

filter :: (v -> Bool) -> InsOrdHashMap k v -> InsOrdHashMap k v Source #

filterWithKey :: (k -> v -> Bool) -> InsOrdHashMap k v -> InsOrdHashMap k v Source #

mapMaybe :: (v -> Maybe v) -> InsOrdHashMap k v -> InsOrdHashMap k v Source #

mapMaybeWithKey :: (k -> v -> Maybe v) -> InsOrdHashMap k v -> InsOrdHashMap k v Source #

Conversions

keys :: InsOrdHashMap k v -> [k] Source #

elems :: InsOrdHashMap k v -> [v] Source #

toList :: InsOrdHashMap k v -> [(k, v)] Source #

toRevList :: InsOrdHashMap k v -> [(k, v)] Source #

fromList :: Hashable k => [(k, v)] -> InsOrdHashMap k v Source #

Lenses

hashMap :: forall k a b p f. (Profunctor p, Functor f) => p (HashMap k a) (f (HashMap k b)) -> p (InsOrdHashMap k a) (f (InsOrdHashMap k b)) Source #

This is a slight lie, as roundtrip doesn't preserve ordering.

unorderedTraversal :: forall k a b f. Applicative f => (a -> f b) -> InsOrdHashMap k a -> f (InsOrdHashMap k b) Source #

Debugging

valid :: (Eq k, Hashable k) => InsOrdHashMap k v -> Bool Source #