{-# LANGUAGE FlexibleContexts          #-}
{-# LANGUAGE FlexibleInstances         #-}
{-# LANGUAGE NoMonomorphismRestriction #-}
{-# LANGUAGE UndecidableInstances      #-}
module Flat.Instances.Mono
  ( sizeSequence
  , encodeSequence
  , decodeSequence
  , sizeList
  , encodeList
  , decodeList
  , sizeSet
  , encodeSet
  , decodeSet
  , sizeMap
  , encodeMap
  , decodeMap
  , AsArray(..)
  , AsList(..)
  , AsSet(..)
  , AsMap(..)
  )
where

import           Data.Containers
import qualified Data.Foldable        as F
import           Data.MonoTraversable (Element, MonoFoldable, ofoldl', otoList)
import           Data.Sequences       (IsSequence)
import qualified Data.Sequences       as S
import           Flat.Instances.Util

{- $setup
>>> import Flat.Instances.Base()
>>> import Flat.Instances.Test
>>> import Data.Word
>>> import qualified Data.Set
>>> import qualified Data.Map
-}

{-|
Sequences are defined as Arrays:

Array v = A0
        | A1 v (Array v)
        | A2 v v (Array v)
        ...
        | A255 ... (Array v)

In practice, this means that the sequence is encoded as a sequence of blocks of up to 255 elements, with every block preceded by the count of the elements in the block and a final 0-length block.

Lists are defined as:

List a ≡  Nil
        | Cons a (List a)

In practice, this means that the list elements will be prefixed with a 1 bit and followed by a final 0 bit.

The AsList/AsArray wrappers can be used to serialise sequences as Lists or Arrays.

Let's see some examples.

>>> flatBits $ AsList [True,True,True]
"1111110"

So we have Cons True (11) repeated three times, followed by a final Nil (0).

The list encoding is the default one for lists so AsList is in this case unnecessary:

>>> flatBits $ [True,True,True]
"1111110"

We can force a list to be encoded as an Array with AsArray:

>>> flatBits $ AsArray [True,True,True]
"00000011 11100000 000"

We have the initial block with a count of 3 (3 == 00000011) followed by the elements True True True (111) and then the final block of 0 elements ("00000 000").

>>> flatBits $ [AsArray [True,True,True]]
"10000001 11110000 00000"

>>> flatBits $ (True,True,True,AsArray $ replicate 7 True)
"11100000 11111111 11000000 00"

>>> flatBits $ AsArray ([]::[()])
"00000000"

>>> flatBits $ AsList ([]::[()])
"0"

>>> tst (AsList [11::Word8,22,33])
(True,28,[133,197,164,32])

>>> tst (AsSet (Data.Set.fromList [11::Word8,22,33]))
(True,28,[133,197,164,32])

>>> tst [AsArray [1..3], AsArray [4..8]]
(True,99,[129,129,2,3,0,65,66,2,131,3,132,0,0])

>>> tst $ [AsArray [(1::Word8)..3], AsArray [4..8]]
(True,99,[129,128,129,1,128,65,65,1,65,129,194,0,0])

>>> tst $ [AsArray [(1::Int)..3]]
(True,42,[129,129,2,3,0,0])
-}
newtype AsArray a =
  AsArray
    { forall a. AsArray a -> a
unArray :: a
    } deriving (Int -> AsArray a -> ShowS
forall a. Show a => Int -> AsArray a -> ShowS
forall a. Show a => [AsArray a] -> ShowS
forall a. Show a => AsArray a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [AsArray a] -> ShowS
$cshowList :: forall a. Show a => [AsArray a] -> ShowS
show :: AsArray a -> String
$cshow :: forall a. Show a => AsArray a -> String
showsPrec :: Int -> AsArray a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> AsArray a -> ShowS
Show,AsArray a -> AsArray a -> Bool
forall a. Eq a => AsArray a -> AsArray a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: AsArray a -> AsArray a -> Bool
$c/= :: forall a. Eq a => AsArray a -> AsArray a -> Bool
== :: AsArray a -> AsArray a -> Bool
$c== :: forall a. Eq a => AsArray a -> AsArray a -> Bool
Eq,AsArray a -> AsArray a -> Bool
AsArray a -> AsArray a -> Ordering
AsArray a -> AsArray a -> AsArray 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 (AsArray a)
forall a. Ord a => AsArray a -> AsArray a -> Bool
forall a. Ord a => AsArray a -> AsArray a -> Ordering
forall a. Ord a => AsArray a -> AsArray a -> AsArray a
min :: AsArray a -> AsArray a -> AsArray a
$cmin :: forall a. Ord a => AsArray a -> AsArray a -> AsArray a
max :: AsArray a -> AsArray a -> AsArray a
$cmax :: forall a. Ord a => AsArray a -> AsArray a -> AsArray a
>= :: AsArray a -> AsArray a -> Bool
$c>= :: forall a. Ord a => AsArray a -> AsArray a -> Bool
> :: AsArray a -> AsArray a -> Bool
$c> :: forall a. Ord a => AsArray a -> AsArray a -> Bool
<= :: AsArray a -> AsArray a -> Bool
$c<= :: forall a. Ord a => AsArray a -> AsArray a -> Bool
< :: AsArray a -> AsArray a -> Bool
$c< :: forall a. Ord a => AsArray a -> AsArray a -> Bool
compare :: AsArray a -> AsArray a -> Ordering
$ccompare :: forall a. Ord a => AsArray a -> AsArray a -> Ordering
Ord)

instance (IsSequence r, Flat (Element r)) => Flat (AsArray r) where
  size :: AsArray r -> Int -> Int
size (AsArray r
a) = forall mono.
(IsSequence mono, Flat (Element mono)) =>
mono -> Int -> Int
sizeSequence r
a
  encode :: AsArray r -> Encoding
encode (AsArray r
a) = forall mono.
(Flat (Element mono), MonoFoldable mono) =>
mono -> Encoding
encodeSequence r
a
  decode :: Get (AsArray r)
decode = forall a. a -> AsArray a
AsArray forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall b. (Flat (Element b), IsSequence b) => Get b
decodeSequence

{- |
Calculate size of an instance of IsSequence as the sum:

* of the size of all the elements

* plus the size of the array constructors (1 byte every 255 elements plus one final byte)
-}
sizeSequence
  :: (IsSequence mono, Flat (Element mono)) => mono -> NumBits -> NumBits
sizeSequence :: forall mono.
(IsSequence mono, Flat (Element mono)) =>
mono -> Int -> Int
sizeSequence mono
s Int
acc =
  let (Int
sz, Int
len) =
          forall mono a.
MonoFoldable mono =>
(a -> Element mono -> a) -> a -> mono -> a
ofoldl' (\(Int
acc, Int
l) Element mono
e -> (forall a. Flat a => a -> Int -> Int
size Element mono
e Int
acc, Int
l forall a. Num a => a -> a -> a
+ Int
1)) (Int
acc, Int
0 :: NumBits) mono
s
  in  Int
sz forall a. Num a => a -> a -> a
+ Int -> Int
arrayBits Int
len
{-# INLINE sizeSequence #-}

-- TODO: check which one is faster
-- sizeSequence s acc = ofoldl' (flip size) acc s + arrayBits (olength s)

-- |Encode an instance of IsSequence, as an array
encodeSequence :: (Flat (Element mono), MonoFoldable mono) => mono -> Encoding
encodeSequence :: forall mono.
(Flat (Element mono), MonoFoldable mono) =>
mono -> Encoding
encodeSequence = forall a. Flat a => [a] -> Encoding
encodeArray forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall mono. MonoFoldable mono => mono -> [Element mono]
otoList
{-# INLINE encodeSequence #-}

-- |Decode an instance of IsSequence, as an array
decodeSequence :: (Flat (Element b), IsSequence b) => Get b
decodeSequence :: forall b. (Flat (Element b), IsSequence b) => Get b
decodeSequence = forall seq. IsSequence seq => [Element seq] -> seq
S.fromList forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. Get a -> Get [a]
decodeArrayWith forall a. Flat a => Get a
decode
{-# INLINE decodeSequence #-}

newtype AsList a =
  AsList
    { forall a. AsList a -> a
unList :: a
    } deriving (Int -> AsList a -> ShowS
forall a. Show a => Int -> AsList a -> ShowS
forall a. Show a => [AsList a] -> ShowS
forall a. Show a => AsList a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [AsList a] -> ShowS
$cshowList :: forall a. Show a => [AsList a] -> ShowS
show :: AsList a -> String
$cshow :: forall a. Show a => AsList a -> String
showsPrec :: Int -> AsList a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> AsList a -> ShowS
Show,AsList a -> AsList a -> Bool
forall a. Eq a => AsList a -> AsList a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: AsList a -> AsList a -> Bool
$c/= :: forall a. Eq a => AsList a -> AsList a -> Bool
== :: AsList a -> AsList a -> Bool
$c== :: forall a. Eq a => AsList a -> AsList a -> Bool
Eq,AsList a -> AsList a -> Bool
AsList a -> AsList a -> Ordering
AsList a -> AsList a -> AsList 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 (AsList a)
forall a. Ord a => AsList a -> AsList a -> Bool
forall a. Ord a => AsList a -> AsList a -> Ordering
forall a. Ord a => AsList a -> AsList a -> AsList a
min :: AsList a -> AsList a -> AsList a
$cmin :: forall a. Ord a => AsList a -> AsList a -> AsList a
max :: AsList a -> AsList a -> AsList a
$cmax :: forall a. Ord a => AsList a -> AsList a -> AsList a
>= :: AsList a -> AsList a -> Bool
$c>= :: forall a. Ord a => AsList a -> AsList a -> Bool
> :: AsList a -> AsList a -> Bool
$c> :: forall a. Ord a => AsList a -> AsList a -> Bool
<= :: AsList a -> AsList a -> Bool
$c<= :: forall a. Ord a => AsList a -> AsList a -> Bool
< :: AsList a -> AsList a -> Bool
$c< :: forall a. Ord a => AsList a -> AsList a -> Bool
compare :: AsList a -> AsList a -> Ordering
$ccompare :: forall a. Ord a => AsList a -> AsList a -> Ordering
Ord)

instance (IsSequence l, Flat (Element l)) => Flat (AsList l) where
  -- size   = sizeList . S.unpack . unList
  -- encode = encodeList . S.unpack . unList
  -- decode = AsList . S.fromList <$> decodeListotoList

  size :: AsList l -> Int -> Int
size   = forall mono.
(MonoFoldable mono, Flat (Element mono)) =>
mono -> Int -> Int
sizeList forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. AsList a -> a
unList
  encode :: AsList l -> Encoding
encode = forall mono.
(Flat (Element mono), MonoFoldable mono) =>
mono -> Encoding
encodeList forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. AsList a -> a
unList
  decode :: Get (AsList l)
decode = forall a. a -> AsList a
AsList forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall b. (IsSequence b, Flat (Element b)) => Get b
decodeList

{-# INLINE sizeList #-}
sizeList
  :: (MonoFoldable mono, Flat (Element mono)) => mono -> NumBits -> NumBits
sizeList :: forall mono.
(MonoFoldable mono, Flat (Element mono)) =>
mono -> Int -> Int
sizeList mono
l Int
sz = forall mono a.
MonoFoldable mono =>
(a -> Element mono -> a) -> a -> mono -> a
ofoldl' (\Int
s Element mono
e -> forall a. Flat a => a -> Int -> Int
size Element mono
e (Int
s forall a. Num a => a -> a -> a
+ Int
1)) (Int
sz forall a. Num a => a -> a -> a
+ Int
1) mono
l

{-# INLINE encodeList #-}
encodeList :: (Flat (Element mono), MonoFoldable mono) => mono -> Encoding
encodeList :: forall mono.
(Flat (Element mono), MonoFoldable mono) =>
mono -> Encoding
encodeList = forall t. (t -> Encoding) -> [t] -> Encoding
encodeListWith forall a. Flat a => a -> Encoding
encode forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall mono. MonoFoldable mono => mono -> [Element mono]
otoList

{-# INLINE decodeList #-}
decodeList :: (IsSequence b, Flat (Element b)) => Get b
decodeList :: forall b. (IsSequence b, Flat (Element b)) => Get b
decodeList = forall seq. IsSequence seq => [Element seq] -> seq
S.fromList forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. Get a -> Get [a]
decodeListWith forall a. Flat a => Get a
decode

{-|
Sets are saved as lists of values.

>>> tstBits $ AsSet (Data.Set.fromList ([False,True,False]::[Bool]))
(True,5,"10110")
-}
newtype AsSet a =
  AsSet
    { forall a. AsSet a -> a
unSet :: a
    } deriving (Int -> AsSet a -> ShowS
forall a. Show a => Int -> AsSet a -> ShowS
forall a. Show a => [AsSet a] -> ShowS
forall a. Show a => AsSet a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [AsSet a] -> ShowS
$cshowList :: forall a. Show a => [AsSet a] -> ShowS
show :: AsSet a -> String
$cshow :: forall a. Show a => AsSet a -> String
showsPrec :: Int -> AsSet a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> AsSet a -> ShowS
Show,AsSet a -> AsSet a -> Bool
forall a. Eq a => AsSet a -> AsSet a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: AsSet a -> AsSet a -> Bool
$c/= :: forall a. Eq a => AsSet a -> AsSet a -> Bool
== :: AsSet a -> AsSet a -> Bool
$c== :: forall a. Eq a => AsSet a -> AsSet a -> Bool
Eq,AsSet a -> AsSet a -> Bool
AsSet a -> AsSet a -> Ordering
AsSet a -> AsSet a -> AsSet 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 (AsSet a)
forall a. Ord a => AsSet a -> AsSet a -> Bool
forall a. Ord a => AsSet a -> AsSet a -> Ordering
forall a. Ord a => AsSet a -> AsSet a -> AsSet a
min :: AsSet a -> AsSet a -> AsSet a
$cmin :: forall a. Ord a => AsSet a -> AsSet a -> AsSet a
max :: AsSet a -> AsSet a -> AsSet a
$cmax :: forall a. Ord a => AsSet a -> AsSet a -> AsSet a
>= :: AsSet a -> AsSet a -> Bool
$c>= :: forall a. Ord a => AsSet a -> AsSet a -> Bool
> :: AsSet a -> AsSet a -> Bool
$c> :: forall a. Ord a => AsSet a -> AsSet a -> Bool
<= :: AsSet a -> AsSet a -> Bool
$c<= :: forall a. Ord a => AsSet a -> AsSet a -> Bool
< :: AsSet a -> AsSet a -> Bool
$c< :: forall a. Ord a => AsSet a -> AsSet a -> Bool
compare :: AsSet a -> AsSet a -> Ordering
$ccompare :: forall a. Ord a => AsSet a -> AsSet a -> Ordering
Ord)

instance (IsSet set, Flat (Element set)) => Flat (AsSet set) where
  size :: AsSet set -> Int -> Int
size   = forall set. (IsSet set, Flat (Element set)) => Size set
sizeSet forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. AsSet a -> a
unSet
  encode :: AsSet set -> Encoding
encode = forall set. (IsSet set, Flat (Element set)) => set -> Encoding
encodeSet forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. AsSet a -> a
unSet
  decode :: Get (AsSet set)
decode = forall a. a -> AsSet a
AsSet forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall set. (IsSet set, Flat (Element set)) => Get set
decodeSet

sizeSet :: (IsSet set, Flat (Element set)) => Size set
sizeSet :: forall set. (IsSet set, Flat (Element set)) => Size set
sizeSet set
l Int
acc = forall mono a.
MonoFoldable mono =>
(a -> Element mono -> a) -> a -> mono -> a
ofoldl' (\Int
acc Element set
e -> forall a. Flat a => a -> Int -> Int
size Element set
e (Int
acc forall a. Num a => a -> a -> a
+ Int
1)) (Int
acc forall a. Num a => a -> a -> a
+ Int
1) set
l
{-# INLINE sizeSet #-}

encodeSet :: (IsSet set, Flat (Element set)) => set -> Encoding
encodeSet :: forall set. (IsSet set, Flat (Element set)) => set -> Encoding
encodeSet = forall mono.
(Flat (Element mono), MonoFoldable mono) =>
mono -> Encoding
encodeList forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall set. IsSet set => set -> [Element set]
setToList
{-# INLINE encodeSet #-}

decodeSet :: (IsSet set, Flat (Element set)) => Get set
decodeSet :: forall set. (IsSet set, Flat (Element set)) => Get set
decodeSet = forall set. IsSet set => [Element set] -> set
setFromList forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall b. (IsSequence b, Flat (Element b)) => Get b
decodeList
{-# INLINE decodeSet #-}

{-|
Maps are saved as lists of (key,value) tuples.

>>> tst (AsMap (Data.Map.fromList ([]::[(Word8,())])))
(True,1,[0])

>>> tst (AsMap (Data.Map.fromList [(3::Word,9::Word)]))
(True,18,[129,132,128])
-}
newtype AsMap a =
  AsMap
    { forall a. AsMap a -> a
unMap :: a
    } deriving (Int -> AsMap a -> ShowS
forall a. Show a => Int -> AsMap a -> ShowS
forall a. Show a => [AsMap a] -> ShowS
forall a. Show a => AsMap a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [AsMap a] -> ShowS
$cshowList :: forall a. Show a => [AsMap a] -> ShowS
show :: AsMap a -> String
$cshow :: forall a. Show a => AsMap a -> String
showsPrec :: Int -> AsMap a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> AsMap a -> ShowS
Show,AsMap a -> AsMap a -> Bool
forall a. Eq a => AsMap a -> AsMap a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: AsMap a -> AsMap a -> Bool
$c/= :: forall a. Eq a => AsMap a -> AsMap a -> Bool
== :: AsMap a -> AsMap a -> Bool
$c== :: forall a. Eq a => AsMap a -> AsMap a -> Bool
Eq,AsMap a -> AsMap a -> Bool
AsMap a -> AsMap a -> Ordering
AsMap a -> AsMap a -> AsMap 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 (AsMap a)
forall a. Ord a => AsMap a -> AsMap a -> Bool
forall a. Ord a => AsMap a -> AsMap a -> Ordering
forall a. Ord a => AsMap a -> AsMap a -> AsMap a
min :: AsMap a -> AsMap a -> AsMap a
$cmin :: forall a. Ord a => AsMap a -> AsMap a -> AsMap a
max :: AsMap a -> AsMap a -> AsMap a
$cmax :: forall a. Ord a => AsMap a -> AsMap a -> AsMap a
>= :: AsMap a -> AsMap a -> Bool
$c>= :: forall a. Ord a => AsMap a -> AsMap a -> Bool
> :: AsMap a -> AsMap a -> Bool
$c> :: forall a. Ord a => AsMap a -> AsMap a -> Bool
<= :: AsMap a -> AsMap a -> Bool
$c<= :: forall a. Ord a => AsMap a -> AsMap a -> Bool
< :: AsMap a -> AsMap a -> Bool
$c< :: forall a. Ord a => AsMap a -> AsMap a -> Bool
compare :: AsMap a -> AsMap a -> Ordering
$ccompare :: forall a. Ord a => AsMap a -> AsMap a -> Ordering
Ord)

instance (IsMap map, Flat (ContainerKey map), Flat (MapValue map)) => Flat (AsMap map) where
  size :: AsMap map -> Int -> Int
size   = forall r.
(Flat (ContainerKey r), Flat (MapValue r), IsMap r) =>
Size r
sizeMap forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. AsMap a -> a
unMap
  encode :: AsMap map -> Encoding
encode = forall map.
(Flat (ContainerKey map), Flat (MapValue map), IsMap map) =>
map -> Encoding
encodeMap forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. AsMap a -> a
unMap
  decode :: Get (AsMap map)
decode = forall a. a -> AsMap a
AsMap forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall map.
(Flat (ContainerKey map), Flat (MapValue map), IsMap map) =>
Get map
decodeMap

{-# INLINE sizeMap #-}
sizeMap :: (Flat (ContainerKey r), Flat (MapValue r), IsMap r) => Size r
sizeMap :: forall r.
(Flat (ContainerKey r), Flat (MapValue r), IsMap r) =>
Size r
sizeMap r
m Int
acc =
  forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
F.foldl' (\Int
acc' (ContainerKey r
k, MapValue r
v) -> forall a. Flat a => a -> Int -> Int
size ContainerKey r
k (forall a. Flat a => a -> Int -> Int
size MapValue r
v (Int
acc' forall a. Num a => a -> a -> a
+ Int
1))) (Int
acc forall a. Num a => a -> a -> a
+ Int
1)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall map. IsMap map => map -> [(ContainerKey map, MapValue map)]
mapToList
    forall a b. (a -> b) -> a -> b
$ r
m
-- sizeMap l sz = ofoldl' (\s (k, v) -> size k (size v (s + 1))) (sz + 1) l

{-# INLINE encodeMap #-}
-- |Encode an instance of IsMap, as a list of (Key,Value) tuples
encodeMap
  :: (Flat (ContainerKey map), Flat (MapValue map), IsMap map)
  => map
  -> Encoding
encodeMap :: forall map.
(Flat (ContainerKey map), Flat (MapValue map), IsMap map) =>
map -> Encoding
encodeMap = forall t. (t -> Encoding) -> [t] -> Encoding
encodeListWith (\(ContainerKey map
k, MapValue map
v) -> forall a. Flat a => a -> Encoding
encode ContainerKey map
k forall a. Semigroup a => a -> a -> a
<> forall a. Flat a => a -> Encoding
encode MapValue map
v) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall map. IsMap map => map -> [(ContainerKey map, MapValue map)]
mapToList

{-# INLINE decodeMap #-}
-- |Decode an instance of IsMap, as a list of (Key,Value) tuples
decodeMap
  :: (Flat (ContainerKey map), Flat (MapValue map), IsMap map) => Get map
decodeMap :: forall map.
(Flat (ContainerKey map), Flat (MapValue map), IsMap map) =>
Get map
decodeMap = forall map. IsMap map => [(ContainerKey map, MapValue map)] -> map
mapFromList forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. Get a -> Get [a]
decodeListWith ((,) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. Flat a => Get a
decode forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall a. Flat a => Get a
decode)