{-# LANGUAGE DerivingStrategies    #-}
{-# LANGUAGE FlexibleContexts      #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE NoImplicitPrelude     #-}
{-# LANGUAGE TemplateHaskell       #-}
{-# LANGUAGE ViewPatterns          #-}

module PlutusTx.Data.AssocMap (
  Map,
  lookup,
  member,
  insert,
  delete,
  singleton,
  empty,
  null,
  toList,
  toBuiltinList,
  safeFromList,
  unsafeFromList,
  unsafeFromBuiltinList,
  noDuplicateKeys,
  all,
  any,
  union,
  unionWith,
  keys,
  map,
  mapThese,
  foldr,
  ) where

import PlutusTx.Builtins qualified as P
import PlutusTx.Builtins.Internal qualified as BI
import PlutusTx.IsData qualified as P
import PlutusTx.Lift (makeLift)
import PlutusTx.List qualified as List
import PlutusTx.Prelude hiding (all, any, foldr, map, null, toList, uncons)
import PlutusTx.Prelude qualified
import PlutusTx.These
import Prettyprinter (Pretty (..))

import Prelude qualified as Haskell

{- | A map associating keys and values backed by `P.BuiltinData`.

This implementation has the following characteristics:

  * The `P.toBuiltinData` and `P.unsafeFromBuiltinData` operations are no-op.
  * Other operations are slower than @PlutusTx.AssocMap.Map@, although equality
    checks on keys can be faster due to `P.equalsData`.
  * Many operations involve converting the keys and\/or values to\/from `P.BuiltinData`.

Therefore this implementation is likely a better choice than "PlutusTx.AssocMap.Map"
if it is part of a data type defined using @asData@, and the key and value types
have efficient `P.toBuiltinData` and `P.unsafeFromBuiltinData` operations (e.g., they
are primitive types or types defined using @asData@).

A `Map` is considered well-defined if it has no duplicate keys. Most operations
preserve the definedness of the resulting `Map` unless otherwise noted.
It is important to observe that, in comparison to standard map implementations,
this implementation provides slow lookup and update operations because it is based
on a list representation.
-}
newtype Map k a = Map (BI.BuiltinList (BI.BuiltinPair BuiltinData BuiltinData))
  deriving stock (Int -> Map k a -> ShowS
[Map k a] -> ShowS
Map k a -> String
(Int -> Map k a -> ShowS)
-> (Map k a -> String) -> ([Map k a] -> ShowS) -> Show (Map k a)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall k a. Int -> Map k a -> ShowS
forall k a. [Map k a] -> ShowS
forall k a. Map k a -> String
$cshowsPrec :: forall k a. Int -> Map k a -> ShowS
showsPrec :: Int -> Map k a -> ShowS
$cshow :: forall k a. Map k a -> String
show :: Map k a -> String
$cshowList :: forall k a. [Map k a] -> ShowS
showList :: [Map k a] -> ShowS
Haskell.Show)

instance P.ToData (Map k a) where
  {-# INLINEABLE toBuiltinData #-}
  toBuiltinData :: Map k a -> BuiltinData
toBuiltinData (Map BuiltinList (BuiltinPair BuiltinData BuiltinData)
d) = BuiltinList (BuiltinPair BuiltinData BuiltinData) -> BuiltinData
BI.mkMap BuiltinList (BuiltinPair BuiltinData BuiltinData)
d
instance P.FromData (Map k a) where
  {-# INLINABLE fromBuiltinData #-}
  fromBuiltinData :: BuiltinData -> Maybe (Map k a)
fromBuiltinData = Map k a -> Maybe (Map k a)
forall a. a -> Maybe a
Just (Map k a -> Maybe (Map k a))
-> (BuiltinData -> Map k a) -> BuiltinData -> Maybe (Map k a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. BuiltinList (BuiltinPair BuiltinData BuiltinData) -> Map k a
forall k a.
BuiltinList (BuiltinPair BuiltinData BuiltinData) -> Map k a
Map (BuiltinList (BuiltinPair BuiltinData BuiltinData) -> Map k a)
-> (BuiltinData
    -> BuiltinList (BuiltinPair BuiltinData BuiltinData))
-> BuiltinData
-> Map k a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. BuiltinData -> BuiltinList (BuiltinPair BuiltinData BuiltinData)
BI.unsafeDataAsMap

instance P.UnsafeFromData (Map k a) where
  {-# INLINABLE unsafeFromBuiltinData #-}
  unsafeFromBuiltinData :: BuiltinData -> Map k a
unsafeFromBuiltinData = BuiltinList (BuiltinPair BuiltinData BuiltinData) -> Map k a
forall k a.
BuiltinList (BuiltinPair BuiltinData BuiltinData) -> Map k a
Map (BuiltinList (BuiltinPair BuiltinData BuiltinData) -> Map k a)
-> (BuiltinData
    -> BuiltinList (BuiltinPair BuiltinData BuiltinData))
-> BuiltinData
-> Map k a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. BuiltinData -> BuiltinList (BuiltinPair BuiltinData BuiltinData)
BI.unsafeDataAsMap

instance
  ( Pretty k
  , Pretty a
  , P.UnsafeFromData k
  , P.UnsafeFromData a
  ) => Pretty (Map k a) where
  pretty :: forall ann. Map k a -> Doc ann
pretty = [(k, a)] -> Doc ann
forall ann. [(k, a)] -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty ([(k, a)] -> Doc ann)
-> (Map k a -> [(k, a)]) -> Map k a -> Doc ann
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Map k a -> [(k, a)]
forall k a.
(UnsafeFromData k, UnsafeFromData a) =>
Map k a -> [(k, a)]
toList

{-# INLINEABLE lookup #-}
-- | Look up the value corresponding to the key.
-- If the `Map` is not well-defined, the result is the value associated with
-- the left-most occurrence of the key in the list.
-- This operation is O(n).
lookup :: forall k a. (P.ToData k, P.UnsafeFromData a) => k -> Map k a -> Maybe a
lookup :: forall k a. (ToData k, UnsafeFromData a) => k -> Map k a -> Maybe a
lookup (k -> BuiltinData
forall a. ToData a => a -> BuiltinData
P.toBuiltinData -> BuiltinData
k) (Map BuiltinList (BuiltinPair BuiltinData BuiltinData)
m) = BuiltinData -> a
forall a. UnsafeFromData a => BuiltinData -> a
P.unsafeFromBuiltinData (BuiltinData -> a) -> Maybe BuiltinData -> Maybe a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> BuiltinData
-> BuiltinList (BuiltinPair BuiltinData BuiltinData)
-> Maybe BuiltinData
lookup' BuiltinData
k BuiltinList (BuiltinPair BuiltinData BuiltinData)
m

lookup'
  :: BuiltinData
  -> BI.BuiltinList (BI.BuiltinPair BuiltinData BuiltinData)
  -> Maybe BuiltinData
lookup' :: BuiltinData
-> BuiltinList (BuiltinPair BuiltinData BuiltinData)
-> Maybe BuiltinData
lookup' BuiltinData
k BuiltinList (BuiltinPair BuiltinData BuiltinData)
m = BuiltinList (BuiltinPair BuiltinData BuiltinData)
-> Maybe BuiltinData
forall {a}. BuiltinList (BuiltinPair BuiltinData a) -> Maybe a
go BuiltinList (BuiltinPair BuiltinData BuiltinData)
m
  where
    go :: BuiltinList (BuiltinPair BuiltinData a) -> Maybe a
go BuiltinList (BuiltinPair BuiltinData a)
xs =
      BuiltinList (BuiltinPair BuiltinData a)
-> (() -> Maybe a)
-> (BuiltinPair BuiltinData a
    -> BuiltinList (BuiltinPair BuiltinData a) -> Maybe a)
-> Maybe a
forall a r.
BuiltinList a -> (() -> r) -> (a -> BuiltinList a -> r) -> r
P.matchList
        BuiltinList (BuiltinPair BuiltinData a)
xs
        (\() -> Maybe a
forall a. Maybe a
Nothing)
        ( \BuiltinPair BuiltinData a
hd ->
            let k' :: BuiltinData
k' = BuiltinPair BuiltinData a -> BuiltinData
forall a b. BuiltinPair a b -> a
BI.fst BuiltinPair BuiltinData a
hd
             in if BuiltinData -> BuiltinData -> Bool
P.equalsData BuiltinData
k BuiltinData
k'
                  then \BuiltinList (BuiltinPair BuiltinData a)
_ -> a -> Maybe a
forall a. a -> Maybe a
Just (BuiltinPair BuiltinData a -> a
forall a b. BuiltinPair a b -> b
BI.snd BuiltinPair BuiltinData a
hd)
                  else BuiltinList (BuiltinPair BuiltinData a) -> Maybe a
go
        )

{-# INLINEABLE member #-}
-- | Check if the key is in the `Map`.
member :: forall k a. (P.ToData k) => k -> Map k a -> Bool
member :: forall k a. ToData k => k -> Map k a -> Bool
member (k -> BuiltinData
forall a. ToData a => a -> BuiltinData
P.toBuiltinData -> BuiltinData
k) (Map BuiltinList (BuiltinPair BuiltinData BuiltinData)
m) = BuiltinData
-> BuiltinList (BuiltinPair BuiltinData BuiltinData) -> Bool
member' BuiltinData
k BuiltinList (BuiltinPair BuiltinData BuiltinData)
m

member' :: BuiltinData -> BI.BuiltinList (BI.BuiltinPair BuiltinData BuiltinData) -> Bool
member' :: BuiltinData
-> BuiltinList (BuiltinPair BuiltinData BuiltinData) -> Bool
member' BuiltinData
k = BuiltinList (BuiltinPair BuiltinData BuiltinData) -> Bool
go
  where
    go :: BI.BuiltinList (BI.BuiltinPair BuiltinData BuiltinData) -> Bool
    go :: BuiltinList (BuiltinPair BuiltinData BuiltinData) -> Bool
go BuiltinList (BuiltinPair BuiltinData BuiltinData)
xs =
      BuiltinList (BuiltinPair BuiltinData BuiltinData)
-> (() -> Bool)
-> (BuiltinPair BuiltinData BuiltinData
    -> BuiltinList (BuiltinPair BuiltinData BuiltinData) -> Bool)
-> Bool
forall a r.
BuiltinList a -> (() -> r) -> (a -> BuiltinList a -> r) -> r
P.matchList
        BuiltinList (BuiltinPair BuiltinData BuiltinData)
xs
        (\() -> Bool
False)
        ( \BuiltinPair BuiltinData BuiltinData
hd ->
            let k' :: BuiltinData
k' = BuiltinPair BuiltinData BuiltinData -> BuiltinData
forall a b. BuiltinPair a b -> a
BI.fst BuiltinPair BuiltinData BuiltinData
hd
             in if BuiltinData -> BuiltinData -> Bool
P.equalsData BuiltinData
k BuiltinData
k'
                  then \BuiltinList (BuiltinPair BuiltinData BuiltinData)
_ -> Bool
True
                  else BuiltinList (BuiltinPair BuiltinData BuiltinData) -> Bool
go
        )

{-# INLINEABLE insert #-}
-- | Insert a key-value pair into the `Map`. If the key is already present,
-- the value is updated.
insert :: forall k a. (P.ToData k, P.ToData a) => k -> a -> Map k a -> Map k a
insert :: forall k a. (ToData k, ToData a) => k -> a -> Map k a -> Map k a
insert (k -> BuiltinData
forall a. ToData a => a -> BuiltinData
P.toBuiltinData -> BuiltinData
k) (a -> BuiltinData
forall a. ToData a => a -> BuiltinData
P.toBuiltinData -> BuiltinData
a) (Map BuiltinList (BuiltinPair BuiltinData BuiltinData)
m) = BuiltinList (BuiltinPair BuiltinData BuiltinData) -> Map k a
forall k a.
BuiltinList (BuiltinPair BuiltinData BuiltinData) -> Map k a
Map (BuiltinList (BuiltinPair BuiltinData BuiltinData) -> Map k a)
-> BuiltinList (BuiltinPair BuiltinData BuiltinData) -> Map k a
forall a b. (a -> b) -> a -> b
$ BuiltinData
-> BuiltinData
-> BuiltinList (BuiltinPair BuiltinData BuiltinData)
-> BuiltinList (BuiltinPair BuiltinData BuiltinData)
insert' BuiltinData
k BuiltinData
a BuiltinList (BuiltinPair BuiltinData BuiltinData)
m

insert'
  :: BuiltinData
  -> BuiltinData
  -> BI.BuiltinList (BI.BuiltinPair BuiltinData BuiltinData)
  -> BI.BuiltinList (BI.BuiltinPair BuiltinData BuiltinData)
insert' :: BuiltinData
-> BuiltinData
-> BuiltinList (BuiltinPair BuiltinData BuiltinData)
-> BuiltinList (BuiltinPair BuiltinData BuiltinData)
insert' BuiltinData
k BuiltinData
a = BuiltinList (BuiltinPair BuiltinData BuiltinData)
-> BuiltinList (BuiltinPair BuiltinData BuiltinData)
go
  where
    go ::
      BI.BuiltinList (BI.BuiltinPair BuiltinData BuiltinData) ->
      BI.BuiltinList (BI.BuiltinPair BuiltinData BuiltinData)
    go :: BuiltinList (BuiltinPair BuiltinData BuiltinData)
-> BuiltinList (BuiltinPair BuiltinData BuiltinData)
go BuiltinList (BuiltinPair BuiltinData BuiltinData)
xs =
      BuiltinList (BuiltinPair BuiltinData BuiltinData)
-> (() -> BuiltinList (BuiltinPair BuiltinData BuiltinData))
-> (BuiltinPair BuiltinData BuiltinData
    -> BuiltinList (BuiltinPair BuiltinData BuiltinData)
    -> BuiltinList (BuiltinPair BuiltinData BuiltinData))
-> BuiltinList (BuiltinPair BuiltinData BuiltinData)
forall a r.
BuiltinList a -> (() -> r) -> (a -> BuiltinList a -> r) -> r
P.matchList
        BuiltinList (BuiltinPair BuiltinData BuiltinData)
xs
        (\() -> BuiltinPair BuiltinData BuiltinData
-> BuiltinList (BuiltinPair BuiltinData BuiltinData)
-> BuiltinList (BuiltinPair BuiltinData BuiltinData)
forall a. a -> BuiltinList a -> BuiltinList a
BI.mkCons (BuiltinData -> BuiltinData -> BuiltinPair BuiltinData BuiltinData
BI.mkPairData BuiltinData
k BuiltinData
a) BuiltinList (BuiltinPair BuiltinData BuiltinData)
nil)
        ( \BuiltinPair BuiltinData BuiltinData
hd BuiltinList (BuiltinPair BuiltinData BuiltinData)
tl ->
            let k' :: BuiltinData
k' = BuiltinPair BuiltinData BuiltinData -> BuiltinData
forall a b. BuiltinPair a b -> a
BI.fst BuiltinPair BuiltinData BuiltinData
hd
             in if BuiltinData -> BuiltinData -> Bool
P.equalsData BuiltinData
k BuiltinData
k'
                  then BuiltinPair BuiltinData BuiltinData
-> BuiltinList (BuiltinPair BuiltinData BuiltinData)
-> BuiltinList (BuiltinPair BuiltinData BuiltinData)
forall a. a -> BuiltinList a -> BuiltinList a
BI.mkCons (BuiltinData -> BuiltinData -> BuiltinPair BuiltinData BuiltinData
BI.mkPairData BuiltinData
k BuiltinData
a) BuiltinList (BuiltinPair BuiltinData BuiltinData)
tl
                  else BuiltinPair BuiltinData BuiltinData
-> BuiltinList (BuiltinPair BuiltinData BuiltinData)
-> BuiltinList (BuiltinPair BuiltinData BuiltinData)
forall a. a -> BuiltinList a -> BuiltinList a
BI.mkCons BuiltinPair BuiltinData BuiltinData
hd (BuiltinList (BuiltinPair BuiltinData BuiltinData)
-> BuiltinList (BuiltinPair BuiltinData BuiltinData)
go BuiltinList (BuiltinPair BuiltinData BuiltinData)
tl)
        )

{-# INLINEABLE delete #-}
-- | Delete a key value pair from the `Map`.
-- If the `Map` is not well-defined, it deletes the pair associated with the
-- left-most occurrence of the key in the list.
delete :: forall k a. (P.ToData k) => k -> Map k a -> Map k a
delete :: forall k a. ToData k => k -> Map k a -> Map k a
delete (k -> BuiltinData
forall a. ToData a => a -> BuiltinData
P.toBuiltinData -> BuiltinData
k) (Map BuiltinList (BuiltinPair BuiltinData BuiltinData)
m) = BuiltinList (BuiltinPair BuiltinData BuiltinData) -> Map k a
forall k a.
BuiltinList (BuiltinPair BuiltinData BuiltinData) -> Map k a
Map (BuiltinList (BuiltinPair BuiltinData BuiltinData) -> Map k a)
-> BuiltinList (BuiltinPair BuiltinData BuiltinData) -> Map k a
forall a b. (a -> b) -> a -> b
$ BuiltinData
-> BuiltinList (BuiltinPair BuiltinData BuiltinData)
-> BuiltinList (BuiltinPair BuiltinData BuiltinData)
delete' BuiltinData
k BuiltinList (BuiltinPair BuiltinData BuiltinData)
m

delete' ::
  BuiltinData ->
  BI.BuiltinList (BI.BuiltinPair BuiltinData BuiltinData) ->
  BI.BuiltinList (BI.BuiltinPair BuiltinData BuiltinData)
delete' :: BuiltinData
-> BuiltinList (BuiltinPair BuiltinData BuiltinData)
-> BuiltinList (BuiltinPair BuiltinData BuiltinData)
delete' BuiltinData
k = BuiltinList (BuiltinPair BuiltinData BuiltinData)
-> BuiltinList (BuiltinPair BuiltinData BuiltinData)
go
  where
    go ::
      BI.BuiltinList (BI.BuiltinPair BuiltinData BuiltinData) ->
      BI.BuiltinList (BI.BuiltinPair BuiltinData BuiltinData)
    go :: BuiltinList (BuiltinPair BuiltinData BuiltinData)
-> BuiltinList (BuiltinPair BuiltinData BuiltinData)
go BuiltinList (BuiltinPair BuiltinData BuiltinData)
xs =
      BuiltinList (BuiltinPair BuiltinData BuiltinData)
-> (() -> BuiltinList (BuiltinPair BuiltinData BuiltinData))
-> (BuiltinPair BuiltinData BuiltinData
    -> BuiltinList (BuiltinPair BuiltinData BuiltinData)
    -> BuiltinList (BuiltinPair BuiltinData BuiltinData))
-> BuiltinList (BuiltinPair BuiltinData BuiltinData)
forall a r.
BuiltinList a -> (() -> r) -> (a -> BuiltinList a -> r) -> r
P.matchList
        BuiltinList (BuiltinPair BuiltinData BuiltinData)
xs
        (\() -> BuiltinList (BuiltinPair BuiltinData BuiltinData)
nil)
        ( \BuiltinPair BuiltinData BuiltinData
hd BuiltinList (BuiltinPair BuiltinData BuiltinData)
tl ->
            let k' :: BuiltinData
k' = BuiltinPair BuiltinData BuiltinData -> BuiltinData
forall a b. BuiltinPair a b -> a
BI.fst BuiltinPair BuiltinData BuiltinData
hd
             in if BuiltinData -> BuiltinData -> Bool
P.equalsData BuiltinData
k BuiltinData
k'
                  then BuiltinList (BuiltinPair BuiltinData BuiltinData)
tl
                  else BuiltinPair BuiltinData BuiltinData
-> BuiltinList (BuiltinPair BuiltinData BuiltinData)
-> BuiltinList (BuiltinPair BuiltinData BuiltinData)
forall a. a -> BuiltinList a -> BuiltinList a
BI.mkCons BuiltinPair BuiltinData BuiltinData
hd (BuiltinList (BuiltinPair BuiltinData BuiltinData)
-> BuiltinList (BuiltinPair BuiltinData BuiltinData)
go BuiltinList (BuiltinPair BuiltinData BuiltinData)
tl)
        )

{-# INLINEABLE singleton #-}
-- | Create an `Map` with a single key-value pair.
singleton :: forall k a. (P.ToData k, P.ToData a) => k -> a -> Map k a
singleton :: forall k a. (ToData k, ToData a) => k -> a -> Map k a
singleton (k -> BuiltinData
forall a. ToData a => a -> BuiltinData
P.toBuiltinData -> BuiltinData
k) (a -> BuiltinData
forall a. ToData a => a -> BuiltinData
P.toBuiltinData -> BuiltinData
a) =
  BuiltinList (BuiltinPair BuiltinData BuiltinData) -> Map k a
forall k a.
BuiltinList (BuiltinPair BuiltinData BuiltinData) -> Map k a
Map (BuiltinList (BuiltinPair BuiltinData BuiltinData) -> Map k a)
-> BuiltinList (BuiltinPair BuiltinData BuiltinData) -> Map k a
forall a b. (a -> b) -> a -> b
$ BuiltinPair BuiltinData BuiltinData
-> BuiltinList (BuiltinPair BuiltinData BuiltinData)
-> BuiltinList (BuiltinPair BuiltinData BuiltinData)
forall a. a -> BuiltinList a -> BuiltinList a
BI.mkCons (BuiltinData -> BuiltinData -> BuiltinPair BuiltinData BuiltinData
BI.mkPairData BuiltinData
k BuiltinData
a) BuiltinList (BuiltinPair BuiltinData BuiltinData)
nil

{-# INLINEABLE empty #-}
-- | An empty `Map`.
empty :: forall k a. Map k a
empty :: forall k a. Map k a
empty = BuiltinList (BuiltinPair BuiltinData BuiltinData) -> Map k a
forall k a.
BuiltinList (BuiltinPair BuiltinData BuiltinData) -> Map k a
Map BuiltinList (BuiltinPair BuiltinData BuiltinData)
nil

{-# INLINEABLE null #-}
-- | Check if the `Map` is empty.
null :: forall k a. Map k a -> Bool
null :: forall k a. Map k a -> Bool
null (Map BuiltinList (BuiltinPair BuiltinData BuiltinData)
m) = BuiltinList (BuiltinPair BuiltinData BuiltinData) -> Bool
forall a. BuiltinList a -> Bool
P.null BuiltinList (BuiltinPair BuiltinData BuiltinData)
m

{-# INLINEABLE safeFromList #-}
-- | Create an `Map` from a list of key-value pairs.
-- In case of duplicates, this function will keep only one entry (the one that precedes).
-- In other words, this function de-duplicates the input list.
safeFromList :: forall k a . (P.ToData k, P.ToData a) => [(k, a)] -> Map k a
safeFromList :: forall k a. (ToData k, ToData a) => [(k, a)] -> Map k a
safeFromList =
  BuiltinList (BuiltinPair BuiltinData BuiltinData) -> Map k a
forall k a.
BuiltinList (BuiltinPair BuiltinData BuiltinData) -> Map k a
Map
    (BuiltinList (BuiltinPair BuiltinData BuiltinData) -> Map k a)
-> ([(k, a)] -> BuiltinList (BuiltinPair BuiltinData BuiltinData))
-> [(k, a)]
-> Map k a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(BuiltinData, BuiltinData)]
-> BuiltinList (BuiltinPair BuiltinData BuiltinData)
forall a arep. HasToOpaque a arep => a -> arep
toOpaque
    ([(BuiltinData, BuiltinData)]
 -> BuiltinList (BuiltinPair BuiltinData BuiltinData))
-> ([(k, a)] -> [(BuiltinData, BuiltinData)])
-> [(k, a)]
-> BuiltinList (BuiltinPair BuiltinData BuiltinData)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((k, a)
 -> [(BuiltinData, BuiltinData)] -> [(BuiltinData, BuiltinData)])
-> [(BuiltinData, BuiltinData)]
-> [(k, a)]
-> [(BuiltinData, BuiltinData)]
forall a b. (a -> b -> b) -> b -> [a] -> b
List.foldr ((k
 -> a
 -> [(BuiltinData, BuiltinData)]
 -> [(BuiltinData, BuiltinData)])
-> (k, a)
-> [(BuiltinData, BuiltinData)]
-> [(BuiltinData, BuiltinData)]
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry k
-> a
-> [(BuiltinData, BuiltinData)]
-> [(BuiltinData, BuiltinData)]
go) []
  where
    go :: k -> a -> [(BuiltinData, BuiltinData)] -> [(BuiltinData, BuiltinData)]
    go :: k
-> a
-> [(BuiltinData, BuiltinData)]
-> [(BuiltinData, BuiltinData)]
go k
k a
v [] = [(k -> BuiltinData
forall a. ToData a => a -> BuiltinData
P.toBuiltinData k
k, a -> BuiltinData
forall a. ToData a => a -> BuiltinData
P.toBuiltinData a
v)]
    go k
k a
v ((BuiltinData
k', BuiltinData
v') : [(BuiltinData, BuiltinData)]
rest) =
      if k -> BuiltinData
forall a. ToData a => a -> BuiltinData
P.toBuiltinData k
k BuiltinData -> BuiltinData -> Bool
forall a. Eq a => a -> a -> Bool
== BuiltinData
k'
        then (k -> BuiltinData
forall a. ToData a => a -> BuiltinData
P.toBuiltinData k
k, a -> BuiltinData
forall a. ToData a => a -> BuiltinData
P.toBuiltinData a
v) (BuiltinData, BuiltinData)
-> [(BuiltinData, BuiltinData)] -> [(BuiltinData, BuiltinData)]
forall a. a -> [a] -> [a]
: k
-> a
-> [(BuiltinData, BuiltinData)]
-> [(BuiltinData, BuiltinData)]
go k
k a
v [(BuiltinData, BuiltinData)]
rest
        else (BuiltinData
k', BuiltinData
v') (BuiltinData, BuiltinData)
-> [(BuiltinData, BuiltinData)] -> [(BuiltinData, BuiltinData)]
forall a. a -> [a] -> [a]
: k
-> a
-> [(BuiltinData, BuiltinData)]
-> [(BuiltinData, BuiltinData)]
go k
k a
v [(BuiltinData, BuiltinData)]
rest

{-# INLINEABLE unsafeFromList #-}
-- | Unsafely create an 'Map' from a list of pairs.
-- This should _only_ be applied to lists which have been checked to not
-- contain duplicate keys, otherwise the resulting 'Map' will contain
-- conflicting entries (two entries sharing the same key), and therefore be ill-defined.
unsafeFromList :: (P.ToData k, P.ToData a) => [(k, a)] -> Map k a
unsafeFromList :: forall k a. (ToData k, ToData a) => [(k, a)] -> Map k a
unsafeFromList =
  BuiltinList (BuiltinPair BuiltinData BuiltinData) -> Map k a
forall k a.
BuiltinList (BuiltinPair BuiltinData BuiltinData) -> Map k a
Map
    (BuiltinList (BuiltinPair BuiltinData BuiltinData) -> Map k a)
-> ([(k, a)] -> BuiltinList (BuiltinPair BuiltinData BuiltinData))
-> [(k, a)]
-> Map k a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(BuiltinData, BuiltinData)]
-> BuiltinList (BuiltinPair BuiltinData BuiltinData)
forall a arep. HasToOpaque a arep => a -> arep
toOpaque
    ([(BuiltinData, BuiltinData)]
 -> BuiltinList (BuiltinPair BuiltinData BuiltinData))
-> ([(k, a)] -> [(BuiltinData, BuiltinData)])
-> [(k, a)]
-> BuiltinList (BuiltinPair BuiltinData BuiltinData)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((k, a) -> (BuiltinData, BuiltinData))
-> [(k, a)] -> [(BuiltinData, BuiltinData)]
forall a b. (a -> b) -> [a] -> [b]
PlutusTx.Prelude.map (\(k
k, a
a) -> (k -> BuiltinData
forall a. ToData a => a -> BuiltinData
P.toBuiltinData k
k, a -> BuiltinData
forall a. ToData a => a -> BuiltinData
P.toBuiltinData a
a))

{-# INLINEABLE noDuplicateKeys #-}
-- | Check if the `Map` is well-defined. Warning: this operation is O(n^2).
noDuplicateKeys :: forall k a. Map k a -> Bool
noDuplicateKeys :: forall k a. Map k a -> Bool
noDuplicateKeys (Map BuiltinList (BuiltinPair BuiltinData BuiltinData)
m) = BuiltinList (BuiltinPair BuiltinData BuiltinData) -> Bool
go BuiltinList (BuiltinPair BuiltinData BuiltinData)
m
  where
    go :: BI.BuiltinList (BI.BuiltinPair BuiltinData BuiltinData) -> Bool
    go :: BuiltinList (BuiltinPair BuiltinData BuiltinData) -> Bool
go BuiltinList (BuiltinPair BuiltinData BuiltinData)
xs =
      BuiltinList (BuiltinPair BuiltinData BuiltinData)
-> (() -> Bool)
-> (BuiltinPair BuiltinData BuiltinData
    -> BuiltinList (BuiltinPair BuiltinData BuiltinData) -> Bool)
-> Bool
forall a r.
BuiltinList a -> (() -> r) -> (a -> BuiltinList a -> r) -> r
P.matchList
        BuiltinList (BuiltinPair BuiltinData BuiltinData)
xs
        (\() -> Bool
True)
        ( \BuiltinPair BuiltinData BuiltinData
hd BuiltinList (BuiltinPair BuiltinData BuiltinData)
tl ->
            let k :: BuiltinData
k = BuiltinPair BuiltinData BuiltinData -> BuiltinData
forall a b. BuiltinPair a b -> a
BI.fst BuiltinPair BuiltinData BuiltinData
hd
             in if BuiltinData
-> BuiltinList (BuiltinPair BuiltinData BuiltinData) -> Bool
member' BuiltinData
k BuiltinList (BuiltinPair BuiltinData BuiltinData)
tl then Bool
False else BuiltinList (BuiltinPair BuiltinData BuiltinData) -> Bool
go BuiltinList (BuiltinPair BuiltinData BuiltinData)
tl
        )

{-# INLINEABLE all #-}
--- | Check if all values in the `Map` satisfy the predicate.
all :: forall k a. (P.UnsafeFromData a) => (a -> Bool) -> Map k a -> Bool
all :: forall k a. UnsafeFromData a => (a -> Bool) -> Map k a -> Bool
all a -> Bool
p (Map BuiltinList (BuiltinPair BuiltinData BuiltinData)
m) = BuiltinList (BuiltinPair BuiltinData BuiltinData) -> Bool
go BuiltinList (BuiltinPair BuiltinData BuiltinData)
m
  where
    go :: BI.BuiltinList (BI.BuiltinPair BuiltinData BuiltinData) -> Bool
    go :: BuiltinList (BuiltinPair BuiltinData BuiltinData) -> Bool
go BuiltinList (BuiltinPair BuiltinData BuiltinData)
xs =
      BuiltinList (BuiltinPair BuiltinData BuiltinData)
-> (() -> Bool)
-> (BuiltinPair BuiltinData BuiltinData
    -> BuiltinList (BuiltinPair BuiltinData BuiltinData) -> Bool)
-> Bool
forall a r.
BuiltinList a -> (() -> r) -> (a -> BuiltinList a -> r) -> r
P.matchList
        BuiltinList (BuiltinPair BuiltinData BuiltinData)
xs
        (\() -> Bool
True)
        ( \BuiltinPair BuiltinData BuiltinData
hd ->
            let a :: a
a = BuiltinData -> a
forall a. UnsafeFromData a => BuiltinData -> a
P.unsafeFromBuiltinData (BuiltinPair BuiltinData BuiltinData -> BuiltinData
forall a b. BuiltinPair a b -> b
BI.snd BuiltinPair BuiltinData BuiltinData
hd)
             in if a -> Bool
p a
a then BuiltinList (BuiltinPair BuiltinData BuiltinData) -> Bool
go else \BuiltinList (BuiltinPair BuiltinData BuiltinData)
_ -> Bool
False
        )

{-# INLINEABLE any #-}
-- | Check if any value in the `Map` satisfies the predicate.
any :: forall k a. (P.UnsafeFromData a) => (a -> Bool) -> Map k a -> Bool
any :: forall k a. UnsafeFromData a => (a -> Bool) -> Map k a -> Bool
any a -> Bool
p (Map BuiltinList (BuiltinPair BuiltinData BuiltinData)
m) = BuiltinList (BuiltinPair BuiltinData BuiltinData) -> Bool
go BuiltinList (BuiltinPair BuiltinData BuiltinData)
m
  where
    go :: BI.BuiltinList (BI.BuiltinPair BuiltinData BuiltinData) -> Bool
    go :: BuiltinList (BuiltinPair BuiltinData BuiltinData) -> Bool
go BuiltinList (BuiltinPair BuiltinData BuiltinData)
xs =
      BuiltinList (BuiltinPair BuiltinData BuiltinData)
-> (() -> Bool)
-> (BuiltinPair BuiltinData BuiltinData
    -> BuiltinList (BuiltinPair BuiltinData BuiltinData) -> Bool)
-> Bool
forall a r.
BuiltinList a -> (() -> r) -> (a -> BuiltinList a -> r) -> r
P.matchList
        BuiltinList (BuiltinPair BuiltinData BuiltinData)
xs
        (\() -> Bool
False)
        ( \BuiltinPair BuiltinData BuiltinData
hd ->
            let a :: a
a = BuiltinData -> a
forall a. UnsafeFromData a => BuiltinData -> a
P.unsafeFromBuiltinData (BuiltinPair BuiltinData BuiltinData -> BuiltinData
forall a b. BuiltinPair a b -> b
BI.snd BuiltinPair BuiltinData BuiltinData
hd)
             in if a -> Bool
p a
a then \BuiltinList (BuiltinPair BuiltinData BuiltinData)
_ -> Bool
True else BuiltinList (BuiltinPair BuiltinData BuiltinData) -> Bool
go
        )

{-# INLINEABLE union #-}

-- | Combine two 'Map's into one. It saves both values if the key is present in both maps.
union ::
  forall k a b.
  (P.UnsafeFromData a, P.UnsafeFromData b, P.ToData a, P.ToData b) =>
  Map k a ->
  Map k b ->
  Map k (These a b)
union :: forall k a b.
(UnsafeFromData a, UnsafeFromData b, ToData a, ToData b) =>
Map k a -> Map k b -> Map k (These a b)
union (Map BuiltinList (BuiltinPair BuiltinData BuiltinData)
ls) (Map BuiltinList (BuiltinPair BuiltinData BuiltinData)
rs) = BuiltinList (BuiltinPair BuiltinData BuiltinData)
-> Map k (These a b)
forall k a.
BuiltinList (BuiltinPair BuiltinData BuiltinData) -> Map k a
Map BuiltinList (BuiltinPair BuiltinData BuiltinData)
res
  where
    goLeft :: BuiltinList (BuiltinPair BuiltinData BuiltinData)
-> BuiltinList (BuiltinPair BuiltinData BuiltinData)
goLeft BuiltinList (BuiltinPair BuiltinData BuiltinData)
xs =
      BuiltinList (BuiltinPair BuiltinData BuiltinData)
-> (() -> BuiltinList (BuiltinPair BuiltinData BuiltinData))
-> (BuiltinPair BuiltinData BuiltinData
    -> BuiltinList (BuiltinPair BuiltinData BuiltinData)
    -> BuiltinList (BuiltinPair BuiltinData BuiltinData))
-> BuiltinList (BuiltinPair BuiltinData BuiltinData)
forall a r.
BuiltinList a -> (() -> r) -> (a -> BuiltinList a -> r) -> r
P.matchList
        BuiltinList (BuiltinPair BuiltinData BuiltinData)
xs
        (\() -> BuiltinList (BuiltinPair BuiltinData BuiltinData)
nil)
        ( \BuiltinPair BuiltinData BuiltinData
hd BuiltinList (BuiltinPair BuiltinData BuiltinData)
tl ->
            let k :: BuiltinData
k = BuiltinPair BuiltinData BuiltinData -> BuiltinData
forall a b. BuiltinPair a b -> a
BI.fst BuiltinPair BuiltinData BuiltinData
hd
                v :: BuiltinData
v = BuiltinPair BuiltinData BuiltinData -> BuiltinData
forall a b. BuiltinPair a b -> b
BI.snd BuiltinPair BuiltinData BuiltinData
hd
                v' :: BuiltinData
v' = case BuiltinData
-> BuiltinList (BuiltinPair BuiltinData BuiltinData)
-> Maybe BuiltinData
lookup' BuiltinData
k BuiltinList (BuiltinPair BuiltinData BuiltinData)
rs of
                  Just BuiltinData
r ->
                    These a b -> BuiltinData
forall a. ToData a => a -> BuiltinData
P.toBuiltinData
                      ( a -> b -> These a b
forall a b. a -> b -> These a b
These
                          (BuiltinData -> a
forall a. UnsafeFromData a => BuiltinData -> a
P.unsafeFromBuiltinData BuiltinData
v)
                          (BuiltinData -> b
forall a. UnsafeFromData a => BuiltinData -> a
P.unsafeFromBuiltinData BuiltinData
r)
                        :: These a b
                      )
                  Maybe BuiltinData
Nothing ->
                    These a b -> BuiltinData
forall a. ToData a => a -> BuiltinData
P.toBuiltinData (a -> These a b
forall a b. a -> These a b
This (BuiltinData -> a
forall a. UnsafeFromData a => BuiltinData -> a
P.unsafeFromBuiltinData BuiltinData
v) :: These a b)
             in BuiltinPair BuiltinData BuiltinData
-> BuiltinList (BuiltinPair BuiltinData BuiltinData)
-> BuiltinList (BuiltinPair BuiltinData BuiltinData)
forall a. a -> BuiltinList a -> BuiltinList a
BI.mkCons (BuiltinData -> BuiltinData -> BuiltinPair BuiltinData BuiltinData
BI.mkPairData BuiltinData
k BuiltinData
v') (BuiltinList (BuiltinPair BuiltinData BuiltinData)
-> BuiltinList (BuiltinPair BuiltinData BuiltinData)
goLeft BuiltinList (BuiltinPair BuiltinData BuiltinData)
tl)
        )

    goRight :: BuiltinList (BuiltinPair BuiltinData BuiltinData)
-> BuiltinList (BuiltinPair BuiltinData BuiltinData)
goRight BuiltinList (BuiltinPair BuiltinData BuiltinData)
xs =
      BuiltinList (BuiltinPair BuiltinData BuiltinData)
-> (() -> BuiltinList (BuiltinPair BuiltinData BuiltinData))
-> (BuiltinPair BuiltinData BuiltinData
    -> BuiltinList (BuiltinPair BuiltinData BuiltinData)
    -> BuiltinList (BuiltinPair BuiltinData BuiltinData))
-> BuiltinList (BuiltinPair BuiltinData BuiltinData)
forall a r.
BuiltinList a -> (() -> r) -> (a -> BuiltinList a -> r) -> r
P.matchList
        BuiltinList (BuiltinPair BuiltinData BuiltinData)
xs
        (\() -> BuiltinList (BuiltinPair BuiltinData BuiltinData)
nil)
        ( \BuiltinPair BuiltinData BuiltinData
hd BuiltinList (BuiltinPair BuiltinData BuiltinData)
tl ->
            let k :: BuiltinData
k = BuiltinPair BuiltinData BuiltinData -> BuiltinData
forall a b. BuiltinPair a b -> a
BI.fst BuiltinPair BuiltinData BuiltinData
hd
                v :: BuiltinData
v = BuiltinPair BuiltinData BuiltinData -> BuiltinData
forall a b. BuiltinPair a b -> b
BI.snd BuiltinPair BuiltinData BuiltinData
hd
                v' :: BuiltinData
v' = case BuiltinData
-> BuiltinList (BuiltinPair BuiltinData BuiltinData)
-> Maybe BuiltinData
lookup' BuiltinData
k BuiltinList (BuiltinPair BuiltinData BuiltinData)
ls of
                  Just BuiltinData
r ->
                    These a b -> BuiltinData
forall a. ToData a => a -> BuiltinData
P.toBuiltinData
                      ( a -> b -> These a b
forall a b. a -> b -> These a b
These
                          (BuiltinData -> a
forall a. UnsafeFromData a => BuiltinData -> a
P.unsafeFromBuiltinData BuiltinData
v)
                          (BuiltinData -> b
forall a. UnsafeFromData a => BuiltinData -> a
P.unsafeFromBuiltinData BuiltinData
r)
                        :: These a b
                      )
                  Maybe BuiltinData
Nothing ->
                    These a b -> BuiltinData
forall a. ToData a => a -> BuiltinData
P.toBuiltinData (b -> These a b
forall a b. b -> These a b
That (BuiltinData -> b
forall a. UnsafeFromData a => BuiltinData -> a
P.unsafeFromBuiltinData BuiltinData
v) :: These a b)
             in BuiltinPair BuiltinData BuiltinData
-> BuiltinList (BuiltinPair BuiltinData BuiltinData)
-> BuiltinList (BuiltinPair BuiltinData BuiltinData)
forall a. a -> BuiltinList a -> BuiltinList a
BI.mkCons (BuiltinData -> BuiltinData -> BuiltinPair BuiltinData BuiltinData
BI.mkPairData BuiltinData
k BuiltinData
v') (BuiltinList (BuiltinPair BuiltinData BuiltinData)
-> BuiltinList (BuiltinPair BuiltinData BuiltinData)
goRight BuiltinList (BuiltinPair BuiltinData BuiltinData)
tl)
        )

    res :: BuiltinList (BuiltinPair BuiltinData BuiltinData)
res = BuiltinList (BuiltinPair BuiltinData BuiltinData)
-> BuiltinList (BuiltinPair BuiltinData BuiltinData)
goLeft BuiltinList (BuiltinPair BuiltinData BuiltinData)
ls BuiltinList (BuiltinPair BuiltinData BuiltinData)
-> BuiltinList (BuiltinPair BuiltinData BuiltinData)
-> BuiltinList (BuiltinPair BuiltinData BuiltinData)
`safeAppend` BuiltinList (BuiltinPair BuiltinData BuiltinData)
-> BuiltinList (BuiltinPair BuiltinData BuiltinData)
goRight BuiltinList (BuiltinPair BuiltinData BuiltinData)
rs

    safeAppend :: BuiltinList (BuiltinPair BuiltinData BuiltinData)
-> BuiltinList (BuiltinPair BuiltinData BuiltinData)
-> BuiltinList (BuiltinPair BuiltinData BuiltinData)
safeAppend BuiltinList (BuiltinPair BuiltinData BuiltinData)
xs1 BuiltinList (BuiltinPair BuiltinData BuiltinData)
xs2 =
      BuiltinList (BuiltinPair BuiltinData BuiltinData)
-> (() -> BuiltinList (BuiltinPair BuiltinData BuiltinData))
-> (BuiltinPair BuiltinData BuiltinData
    -> BuiltinList (BuiltinPair BuiltinData BuiltinData)
    -> BuiltinList (BuiltinPair BuiltinData BuiltinData))
-> BuiltinList (BuiltinPair BuiltinData BuiltinData)
forall a r.
BuiltinList a -> (() -> r) -> (a -> BuiltinList a -> r) -> r
P.matchList
        BuiltinList (BuiltinPair BuiltinData BuiltinData)
xs1
        (\() -> BuiltinList (BuiltinPair BuiltinData BuiltinData)
xs2)
        ( \BuiltinPair BuiltinData BuiltinData
hd BuiltinList (BuiltinPair BuiltinData BuiltinData)
tl ->
            let k :: BuiltinData
k = BuiltinPair BuiltinData BuiltinData -> BuiltinData
forall a b. BuiltinPair a b -> a
BI.fst BuiltinPair BuiltinData BuiltinData
hd
                v :: BuiltinData
v = BuiltinPair BuiltinData BuiltinData -> BuiltinData
forall a b. BuiltinPair a b -> b
BI.snd BuiltinPair BuiltinData BuiltinData
hd
             in BuiltinData
-> BuiltinData
-> BuiltinList (BuiltinPair BuiltinData BuiltinData)
-> BuiltinList (BuiltinPair BuiltinData BuiltinData)
insert' BuiltinData
k BuiltinData
v (BuiltinList (BuiltinPair BuiltinData BuiltinData)
-> BuiltinList (BuiltinPair BuiltinData BuiltinData)
-> BuiltinList (BuiltinPair BuiltinData BuiltinData)
safeAppend BuiltinList (BuiltinPair BuiltinData BuiltinData)
tl BuiltinList (BuiltinPair BuiltinData BuiltinData)
xs2)
        )

{-# INLINEABLE unionWith #-}
-- | Combine two 'Map's with the given combination function.
unionWith ::
  forall k a.
  (P.UnsafeFromData a, P.ToData a) =>
  (a -> a -> a) ->
  Map k a ->
  Map k a ->
  Map k a
unionWith :: forall k a.
(UnsafeFromData a, ToData a) =>
(a -> a -> a) -> Map k a -> Map k a -> Map k a
unionWith a -> a -> a
f (Map BuiltinList (BuiltinPair BuiltinData BuiltinData)
ls) (Map BuiltinList (BuiltinPair BuiltinData BuiltinData)
rs) =
  BuiltinList (BuiltinPair BuiltinData BuiltinData) -> Map k a
forall k a.
BuiltinList (BuiltinPair BuiltinData BuiltinData) -> Map k a
Map BuiltinList (BuiltinPair BuiltinData BuiltinData)
res
  where
    ls' :: BI.BuiltinList (BI.BuiltinPair BuiltinData BuiltinData)
    ls' :: BuiltinList (BuiltinPair BuiltinData BuiltinData)
ls' = BuiltinList (BuiltinPair BuiltinData BuiltinData)
-> BuiltinList (BuiltinPair BuiltinData BuiltinData)
go BuiltinList (BuiltinPair BuiltinData BuiltinData)
ls
      where
        go :: BuiltinList (BuiltinPair BuiltinData BuiltinData)
-> BuiltinList (BuiltinPair BuiltinData BuiltinData)
go BuiltinList (BuiltinPair BuiltinData BuiltinData)
xs =
          BuiltinList (BuiltinPair BuiltinData BuiltinData)
-> (() -> BuiltinList (BuiltinPair BuiltinData BuiltinData))
-> (BuiltinPair BuiltinData BuiltinData
    -> BuiltinList (BuiltinPair BuiltinData BuiltinData)
    -> BuiltinList (BuiltinPair BuiltinData BuiltinData))
-> BuiltinList (BuiltinPair BuiltinData BuiltinData)
forall a r.
BuiltinList a -> (() -> r) -> (a -> BuiltinList a -> r) -> r
P.matchList
            BuiltinList (BuiltinPair BuiltinData BuiltinData)
xs
            (\() -> BuiltinList (BuiltinPair BuiltinData BuiltinData)
nil)
            ( \BuiltinPair BuiltinData BuiltinData
hd BuiltinList (BuiltinPair BuiltinData BuiltinData)
tl ->
                let k' :: BuiltinData
k' = BuiltinPair BuiltinData BuiltinData -> BuiltinData
forall a b. BuiltinPair a b -> a
BI.fst BuiltinPair BuiltinData BuiltinData
hd
                    v' :: BuiltinData
v' = BuiltinPair BuiltinData BuiltinData -> BuiltinData
forall a b. BuiltinPair a b -> b
BI.snd BuiltinPair BuiltinData BuiltinData
hd
                    v'' :: BuiltinData
v'' = case BuiltinData
-> BuiltinList (BuiltinPair BuiltinData BuiltinData)
-> Maybe BuiltinData
lookup' BuiltinData
k' BuiltinList (BuiltinPair BuiltinData BuiltinData)
rs of
                      Just BuiltinData
r ->
                        a -> BuiltinData
forall a. ToData a => a -> BuiltinData
P.toBuiltinData
                          (a -> a -> a
f (BuiltinData -> a
forall a. UnsafeFromData a => BuiltinData -> a
P.unsafeFromBuiltinData BuiltinData
v') (BuiltinData -> a
forall a. UnsafeFromData a => BuiltinData -> a
P.unsafeFromBuiltinData BuiltinData
r))
                      Maybe BuiltinData
Nothing -> BuiltinData
v'
                 in BuiltinPair BuiltinData BuiltinData
-> BuiltinList (BuiltinPair BuiltinData BuiltinData)
-> BuiltinList (BuiltinPair BuiltinData BuiltinData)
forall a. a -> BuiltinList a -> BuiltinList a
BI.mkCons (BuiltinData -> BuiltinData -> BuiltinPair BuiltinData BuiltinData
BI.mkPairData BuiltinData
k' BuiltinData
v'') (BuiltinList (BuiltinPair BuiltinData BuiltinData)
-> BuiltinList (BuiltinPair BuiltinData BuiltinData)
go BuiltinList (BuiltinPair BuiltinData BuiltinData)
tl)
            )

    rs' :: BI.BuiltinList (BI.BuiltinPair BuiltinData BuiltinData)
    rs' :: BuiltinList (BuiltinPair BuiltinData BuiltinData)
rs' = BuiltinList (BuiltinPair BuiltinData BuiltinData)
-> BuiltinList (BuiltinPair BuiltinData BuiltinData)
go BuiltinList (BuiltinPair BuiltinData BuiltinData)
rs
      where
        go :: BuiltinList (BuiltinPair BuiltinData BuiltinData)
-> BuiltinList (BuiltinPair BuiltinData BuiltinData)
go BuiltinList (BuiltinPair BuiltinData BuiltinData)
xs =
          BuiltinList (BuiltinPair BuiltinData BuiltinData)
-> (() -> BuiltinList (BuiltinPair BuiltinData BuiltinData))
-> (BuiltinPair BuiltinData BuiltinData
    -> BuiltinList (BuiltinPair BuiltinData BuiltinData)
    -> BuiltinList (BuiltinPair BuiltinData BuiltinData))
-> BuiltinList (BuiltinPair BuiltinData BuiltinData)
forall a r.
BuiltinList a -> (() -> r) -> (a -> BuiltinList a -> r) -> r
P.matchList
            BuiltinList (BuiltinPair BuiltinData BuiltinData)
xs
            (\() -> BuiltinList (BuiltinPair BuiltinData BuiltinData)
nil)
            ( \BuiltinPair BuiltinData BuiltinData
hd BuiltinList (BuiltinPair BuiltinData BuiltinData)
tl ->
                let k' :: BuiltinData
k' = BuiltinPair BuiltinData BuiltinData -> BuiltinData
forall a b. BuiltinPair a b -> a
BI.fst BuiltinPair BuiltinData BuiltinData
hd
                    tl' :: BuiltinList (BuiltinPair BuiltinData BuiltinData)
tl' = BuiltinList (BuiltinPair BuiltinData BuiltinData)
-> BuiltinList (BuiltinPair BuiltinData BuiltinData)
go BuiltinList (BuiltinPair BuiltinData BuiltinData)
tl
                 in if BuiltinData
-> BuiltinList (BuiltinPair BuiltinData BuiltinData) -> Bool
member' BuiltinData
k' BuiltinList (BuiltinPair BuiltinData BuiltinData)
ls
                      then BuiltinList (BuiltinPair BuiltinData BuiltinData)
tl'
                      else BuiltinPair BuiltinData BuiltinData
-> BuiltinList (BuiltinPair BuiltinData BuiltinData)
-> BuiltinList (BuiltinPair BuiltinData BuiltinData)
forall a. a -> BuiltinList a -> BuiltinList a
BI.mkCons BuiltinPair BuiltinData BuiltinData
hd BuiltinList (BuiltinPair BuiltinData BuiltinData)
tl'
            )

    res :: BI.BuiltinList (BI.BuiltinPair BuiltinData BuiltinData)
    res :: BuiltinList (BuiltinPair BuiltinData BuiltinData)
res = BuiltinList (BuiltinPair BuiltinData BuiltinData)
-> BuiltinList (BuiltinPair BuiltinData BuiltinData)
-> BuiltinList (BuiltinPair BuiltinData BuiltinData)
forall {a}. BuiltinList a -> BuiltinList a -> BuiltinList a
go BuiltinList (BuiltinPair BuiltinData BuiltinData)
rs' BuiltinList (BuiltinPair BuiltinData BuiltinData)
ls'
      where
        go :: BuiltinList a -> BuiltinList a -> BuiltinList a
go BuiltinList a
acc BuiltinList a
xs =
          BuiltinList a
-> (() -> BuiltinList a)
-> (a -> BuiltinList a -> BuiltinList a)
-> BuiltinList a
forall a r.
BuiltinList a -> (() -> r) -> (a -> BuiltinList a -> r) -> r
P.matchList
            BuiltinList a
xs
            (\() -> BuiltinList a
acc)
            (\a
hd -> BuiltinList a -> BuiltinList a -> BuiltinList a
go (a -> BuiltinList a -> BuiltinList a
forall a. a -> BuiltinList a -> BuiltinList a
BI.mkCons a
hd BuiltinList a
acc))

{-# INLINEABLE toList #-}
-- | Convert the `Map` to a list of key-value pairs. This operation is O(n).
-- See 'toBuiltinList' for a more efficient alternative.
toList :: (P.UnsafeFromData k, P.UnsafeFromData a) => Map k a -> [(k, a)]
toList :: forall k a.
(UnsafeFromData k, UnsafeFromData a) =>
Map k a -> [(k, a)]
toList Map k a
d = BuiltinList (BuiltinPair BuiltinData BuiltinData) -> [(k, a)]
forall {a} {b}.
(UnsafeFromData a, UnsafeFromData b) =>
BuiltinList (BuiltinPair BuiltinData BuiltinData) -> [(a, b)]
go (Map k a -> BuiltinList (BuiltinPair BuiltinData BuiltinData)
forall k a.
Map k a -> BuiltinList (BuiltinPair BuiltinData BuiltinData)
toBuiltinList Map k a
d)
  where
    go :: BuiltinList (BuiltinPair BuiltinData BuiltinData) -> [(a, b)]
go BuiltinList (BuiltinPair BuiltinData BuiltinData)
xs =
      BuiltinList (BuiltinPair BuiltinData BuiltinData)
-> (() -> [(a, b)])
-> (BuiltinPair BuiltinData BuiltinData
    -> BuiltinList (BuiltinPair BuiltinData BuiltinData) -> [(a, b)])
-> [(a, b)]
forall a r.
BuiltinList a -> (() -> r) -> (a -> BuiltinList a -> r) -> r
P.matchList
        BuiltinList (BuiltinPair BuiltinData BuiltinData)
xs
        (\() -> [])
        ( \BuiltinPair BuiltinData BuiltinData
hd BuiltinList (BuiltinPair BuiltinData BuiltinData)
tl ->
            (BuiltinData -> a
forall a. UnsafeFromData a => BuiltinData -> a
P.unsafeFromBuiltinData (BuiltinPair BuiltinData BuiltinData -> BuiltinData
forall a b. BuiltinPair a b -> a
BI.fst BuiltinPair BuiltinData BuiltinData
hd), BuiltinData -> b
forall a. UnsafeFromData a => BuiltinData -> a
P.unsafeFromBuiltinData (BuiltinPair BuiltinData BuiltinData -> BuiltinData
forall a b. BuiltinPair a b -> b
BI.snd BuiltinPair BuiltinData BuiltinData
hd))
              (a, b) -> [(a, b)] -> [(a, b)]
forall a. a -> [a] -> [a]
: BuiltinList (BuiltinPair BuiltinData BuiltinData) -> [(a, b)]
go BuiltinList (BuiltinPair BuiltinData BuiltinData)
tl
        )

{-# INLINEABLE toBuiltinList #-}
-- | Convert the `Map` to a `P.BuiltinList` of key-value pairs. This operation is O(1).
toBuiltinList :: Map k a -> BI.BuiltinList (BI.BuiltinPair BuiltinData BuiltinData)
toBuiltinList :: forall k a.
Map k a -> BuiltinList (BuiltinPair BuiltinData BuiltinData)
toBuiltinList (Map BuiltinList (BuiltinPair BuiltinData BuiltinData)
d) = BuiltinList (BuiltinPair BuiltinData BuiltinData)
d

{-# INLINEABLE unsafeFromBuiltinList #-}
-- | Unsafely create an 'Map' from a `P.BuiltinList` of key-value pairs.
-- This function is unsafe because it assumes that the elements of the list can be safely
-- decoded from their 'BuiltinData' representation.
unsafeFromBuiltinList ::
  forall k a.
  BI.BuiltinList (BI.BuiltinPair BuiltinData BuiltinData) ->
  Map k a
unsafeFromBuiltinList :: forall k a.
BuiltinList (BuiltinPair BuiltinData BuiltinData) -> Map k a
unsafeFromBuiltinList = BuiltinList (BuiltinPair BuiltinData BuiltinData) -> Map k a
forall k a.
BuiltinList (BuiltinPair BuiltinData BuiltinData) -> Map k a
Map

{-# INLINEABLE nil #-}
-- | An empty `P.BuiltinList` of key-value pairs.
nil :: BI.BuiltinList (BI.BuiltinPair BuiltinData BuiltinData)
nil :: BuiltinList (BuiltinPair BuiltinData BuiltinData)
nil = BuiltinList (BuiltinPair BuiltinData BuiltinData)
forall arep. MkNil arep => BuiltinList arep
P.mkNil

keys'
  :: BI.BuiltinList (BI.BuiltinPair BuiltinData BuiltinData)
  -> BI.BuiltinList BuiltinData
keys' :: BuiltinList (BuiltinPair BuiltinData BuiltinData)
-> BuiltinList BuiltinData
keys' = BuiltinList (BuiltinPair BuiltinData BuiltinData)
-> BuiltinList BuiltinData
forall {arep} {b}.
MkNil arep =>
BuiltinList (BuiltinPair arep b) -> BuiltinList arep
go
  where
    go :: BuiltinList (BuiltinPair arep b) -> BuiltinList arep
go BuiltinList (BuiltinPair arep b)
xs =
      BuiltinList (BuiltinPair arep b)
-> (() -> BuiltinList arep)
-> (BuiltinPair arep b
    -> BuiltinList (BuiltinPair arep b) -> BuiltinList arep)
-> BuiltinList arep
forall a r.
BuiltinList a -> (() -> r) -> (a -> BuiltinList a -> r) -> r
P.matchList
        BuiltinList (BuiltinPair arep b)
xs
        (\() -> BuiltinList arep
forall arep. MkNil arep => BuiltinList arep
P.mkNil)
        ( \BuiltinPair arep b
hd BuiltinList (BuiltinPair arep b)
tl ->
            let k :: arep
k = BuiltinPair arep b -> arep
forall a b. BuiltinPair a b -> a
BI.fst BuiltinPair arep b
hd
             in arep -> BuiltinList arep -> BuiltinList arep
forall a. a -> BuiltinList a -> BuiltinList a
BI.mkCons arep
k (BuiltinList (BuiltinPair arep b) -> BuiltinList arep
go BuiltinList (BuiltinPair arep b)
tl)
        )

{-# INLINEABLE keys #-}
keys :: forall k a. Map k a -> BI.BuiltinList BuiltinData
keys :: forall k a. Map k a -> BuiltinList BuiltinData
keys (Map BuiltinList (BuiltinPair BuiltinData BuiltinData)
m) = BuiltinList (BuiltinPair BuiltinData BuiltinData)
-> BuiltinList BuiltinData
keys' BuiltinList (BuiltinPair BuiltinData BuiltinData)
m

{-# INLINEABLE mapThese #-}
mapThese
  :: forall v k a b
  . ( P.ToData a, P.ToData b, P.UnsafeFromData v)
  => (v -> These a b) -> Map k v -> (Map k a, Map k b)
mapThese :: forall v k a b.
(ToData a, ToData b, UnsafeFromData v) =>
(v -> These a b) -> Map k v -> (Map k a, Map k b)
mapThese v -> These a b
f (Map BuiltinList (BuiltinPair BuiltinData BuiltinData)
m) = (BuiltinList (BuiltinPair BuiltinData BuiltinData) -> Map k a
forall k a.
BuiltinList (BuiltinPair BuiltinData BuiltinData) -> Map k a
Map BuiltinList (BuiltinPair BuiltinData BuiltinData)
ls, BuiltinList (BuiltinPair BuiltinData BuiltinData) -> Map k b
forall k a.
BuiltinList (BuiltinPair BuiltinData BuiltinData) -> Map k a
Map BuiltinList (BuiltinPair BuiltinData BuiltinData)
rs)
  where
    (BuiltinList (BuiltinPair BuiltinData BuiltinData)
ls, BuiltinList (BuiltinPair BuiltinData BuiltinData)
rs) = BuiltinList (BuiltinPair BuiltinData BuiltinData)
-> (BuiltinList (BuiltinPair BuiltinData BuiltinData),
    BuiltinList (BuiltinPair BuiltinData BuiltinData))
go BuiltinList (BuiltinPair BuiltinData BuiltinData)
m
    go
      :: BI.BuiltinList (BI.BuiltinPair BuiltinData BuiltinData)
      ->
        ( BI.BuiltinList (BI.BuiltinPair BuiltinData BuiltinData)
        , BI.BuiltinList (BI.BuiltinPair BuiltinData BuiltinData)
        )
    go :: BuiltinList (BuiltinPair BuiltinData BuiltinData)
-> (BuiltinList (BuiltinPair BuiltinData BuiltinData),
    BuiltinList (BuiltinPair BuiltinData BuiltinData))
go BuiltinList (BuiltinPair BuiltinData BuiltinData)
xs =
      BuiltinList (BuiltinPair BuiltinData BuiltinData)
-> (()
    -> (BuiltinList (BuiltinPair BuiltinData BuiltinData),
        BuiltinList (BuiltinPair BuiltinData BuiltinData)))
-> (BuiltinPair BuiltinData BuiltinData
    -> BuiltinList (BuiltinPair BuiltinData BuiltinData)
    -> (BuiltinList (BuiltinPair BuiltinData BuiltinData),
        BuiltinList (BuiltinPair BuiltinData BuiltinData)))
-> (BuiltinList (BuiltinPair BuiltinData BuiltinData),
    BuiltinList (BuiltinPair BuiltinData BuiltinData))
forall a r.
BuiltinList a -> (() -> r) -> (a -> BuiltinList a -> r) -> r
P.matchList
        BuiltinList (BuiltinPair BuiltinData BuiltinData)
xs
        (\() -> (BuiltinList (BuiltinPair BuiltinData BuiltinData)
nil, BuiltinList (BuiltinPair BuiltinData BuiltinData)
nil))
        ( \BuiltinPair BuiltinData BuiltinData
hd BuiltinList (BuiltinPair BuiltinData BuiltinData)
tl ->
            let k :: BuiltinData
k = BuiltinPair BuiltinData BuiltinData -> BuiltinData
forall a b. BuiltinPair a b -> a
BI.fst BuiltinPair BuiltinData BuiltinData
hd
                v :: BuiltinData
v = BuiltinPair BuiltinData BuiltinData -> BuiltinData
forall a b. BuiltinPair a b -> b
BI.snd BuiltinPair BuiltinData BuiltinData
hd
                (BuiltinList (BuiltinPair BuiltinData BuiltinData)
ls', BuiltinList (BuiltinPair BuiltinData BuiltinData)
rs') = BuiltinList (BuiltinPair BuiltinData BuiltinData)
-> (BuiltinList (BuiltinPair BuiltinData BuiltinData),
    BuiltinList (BuiltinPair BuiltinData BuiltinData))
go BuiltinList (BuiltinPair BuiltinData BuiltinData)
tl
             in case BuiltinData -> These a b
f' BuiltinData
v of
                  This a
l' -> (BuiltinPair BuiltinData BuiltinData
-> BuiltinList (BuiltinPair BuiltinData BuiltinData)
-> BuiltinList (BuiltinPair BuiltinData BuiltinData)
forall a. a -> BuiltinList a -> BuiltinList a
BI.mkCons (BuiltinData -> BuiltinData -> BuiltinPair BuiltinData BuiltinData
BI.mkPairData BuiltinData
k (a -> BuiltinData
forall a. ToData a => a -> BuiltinData
P.toBuiltinData a
l')) BuiltinList (BuiltinPair BuiltinData BuiltinData)
ls', BuiltinList (BuiltinPair BuiltinData BuiltinData)
rs')
                  That b
r' -> (BuiltinList (BuiltinPair BuiltinData BuiltinData)
ls', BuiltinPair BuiltinData BuiltinData
-> BuiltinList (BuiltinPair BuiltinData BuiltinData)
-> BuiltinList (BuiltinPair BuiltinData BuiltinData)
forall a. a -> BuiltinList a -> BuiltinList a
BI.mkCons (BuiltinData -> BuiltinData -> BuiltinPair BuiltinData BuiltinData
BI.mkPairData BuiltinData
k (b -> BuiltinData
forall a. ToData a => a -> BuiltinData
P.toBuiltinData b
r')) BuiltinList (BuiltinPair BuiltinData BuiltinData)
rs')
                  These a
l' b
r' ->
                    ( BuiltinPair BuiltinData BuiltinData
-> BuiltinList (BuiltinPair BuiltinData BuiltinData)
-> BuiltinList (BuiltinPair BuiltinData BuiltinData)
forall a. a -> BuiltinList a -> BuiltinList a
BI.mkCons (BuiltinData -> BuiltinData -> BuiltinPair BuiltinData BuiltinData
BI.mkPairData BuiltinData
k (a -> BuiltinData
forall a. ToData a => a -> BuiltinData
P.toBuiltinData a
l')) BuiltinList (BuiltinPair BuiltinData BuiltinData)
ls'
                    , BuiltinPair BuiltinData BuiltinData
-> BuiltinList (BuiltinPair BuiltinData BuiltinData)
-> BuiltinList (BuiltinPair BuiltinData BuiltinData)
forall a. a -> BuiltinList a -> BuiltinList a
BI.mkCons (BuiltinData -> BuiltinData -> BuiltinPair BuiltinData BuiltinData
BI.mkPairData BuiltinData
k (b -> BuiltinData
forall a. ToData a => a -> BuiltinData
P.toBuiltinData b
r')) BuiltinList (BuiltinPair BuiltinData BuiltinData)
rs'
                    )
        )
    f' :: BuiltinData -> These a b
    f' :: BuiltinData -> These a b
f' = v -> These a b
f (v -> These a b) -> (BuiltinData -> v) -> BuiltinData -> These a b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. BuiltinData -> v
forall a. UnsafeFromData a => BuiltinData -> a
P.unsafeFromBuiltinData

{-# INLINEABLE map #-}
map :: forall k a b. (P.UnsafeFromData a, P.ToData b) => (a -> b) -> Map k a -> Map k b
map :: forall k a b.
(UnsafeFromData a, ToData b) =>
(a -> b) -> Map k a -> Map k b
map a -> b
f (Map BuiltinList (BuiltinPair BuiltinData BuiltinData)
m) = BuiltinList (BuiltinPair BuiltinData BuiltinData) -> Map k b
forall k a.
BuiltinList (BuiltinPair BuiltinData BuiltinData) -> Map k a
Map (BuiltinList (BuiltinPair BuiltinData BuiltinData) -> Map k b)
-> BuiltinList (BuiltinPair BuiltinData BuiltinData) -> Map k b
forall a b. (a -> b) -> a -> b
$ BuiltinList (BuiltinPair BuiltinData BuiltinData)
-> BuiltinList (BuiltinPair BuiltinData BuiltinData)
go BuiltinList (BuiltinPair BuiltinData BuiltinData)
m
  where
    go :: BuiltinList (BuiltinPair BuiltinData BuiltinData)
-> BuiltinList (BuiltinPair BuiltinData BuiltinData)
go BuiltinList (BuiltinPair BuiltinData BuiltinData)
xs =
      BuiltinList (BuiltinPair BuiltinData BuiltinData)
-> (() -> BuiltinList (BuiltinPair BuiltinData BuiltinData))
-> (BuiltinPair BuiltinData BuiltinData
    -> BuiltinList (BuiltinPair BuiltinData BuiltinData)
    -> BuiltinList (BuiltinPair BuiltinData BuiltinData))
-> BuiltinList (BuiltinPair BuiltinData BuiltinData)
forall a r.
BuiltinList a -> (() -> r) -> (a -> BuiltinList a -> r) -> r
P.matchList
        BuiltinList (BuiltinPair BuiltinData BuiltinData)
xs
        (\() -> BuiltinList (BuiltinPair BuiltinData BuiltinData)
nil)
        ( \BuiltinPair BuiltinData BuiltinData
hd BuiltinList (BuiltinPair BuiltinData BuiltinData)
tl ->
            let k :: BuiltinData
k = BuiltinPair BuiltinData BuiltinData -> BuiltinData
forall a b. BuiltinPair a b -> a
BI.fst BuiltinPair BuiltinData BuiltinData
hd
                v :: BuiltinData
v = BuiltinPair BuiltinData BuiltinData -> BuiltinData
forall a b. BuiltinPair a b -> b
BI.snd BuiltinPair BuiltinData BuiltinData
hd
             in
              BuiltinPair BuiltinData BuiltinData
-> BuiltinList (BuiltinPair BuiltinData BuiltinData)
-> BuiltinList (BuiltinPair BuiltinData BuiltinData)
forall a. a -> BuiltinList a -> BuiltinList a
BI.mkCons
                (BuiltinData -> BuiltinData -> BuiltinPair BuiltinData BuiltinData
BI.mkPairData BuiltinData
k (b -> BuiltinData
forall a. ToData a => a -> BuiltinData
P.toBuiltinData (a -> b
f (BuiltinData -> a
forall a. UnsafeFromData a => BuiltinData -> a
P.unsafeFromBuiltinData BuiltinData
v))))
                (BuiltinList (BuiltinPair BuiltinData BuiltinData)
-> BuiltinList (BuiltinPair BuiltinData BuiltinData)
go BuiltinList (BuiltinPair BuiltinData BuiltinData)
tl)
        )

{-# INLINEABLE foldr #-}
foldr :: forall a b k. (P.UnsafeFromData a) => (a -> b -> b) -> b -> Map k a -> b
foldr :: forall a b k.
UnsafeFromData a =>
(a -> b -> b) -> b -> Map k a -> b
foldr a -> b -> b
f b
z (Map BuiltinList (BuiltinPair BuiltinData BuiltinData)
m) = BuiltinList (BuiltinPair BuiltinData BuiltinData) -> b
forall {a}. BuiltinList (BuiltinPair a BuiltinData) -> b
go BuiltinList (BuiltinPair BuiltinData BuiltinData)
m
  where
    go :: BuiltinList (BuiltinPair a BuiltinData) -> b
go BuiltinList (BuiltinPair a BuiltinData)
xs =
      BuiltinList (BuiltinPair a BuiltinData)
-> (() -> b)
-> (BuiltinPair a BuiltinData
    -> BuiltinList (BuiltinPair a BuiltinData) -> b)
-> b
forall a r.
BuiltinList a -> (() -> r) -> (a -> BuiltinList a -> r) -> r
P.matchList
        BuiltinList (BuiltinPair a BuiltinData)
xs
        (\() -> b
z)
        ( \BuiltinPair a BuiltinData
hd BuiltinList (BuiltinPair a BuiltinData)
tl ->
            let v :: BuiltinData
v = BuiltinPair a BuiltinData -> BuiltinData
forall a b. BuiltinPair a b -> b
BI.snd BuiltinPair a BuiltinData
hd
             in a -> b -> b
f (BuiltinData -> a
forall a. UnsafeFromData a => BuiltinData -> a
P.unsafeFromBuiltinData BuiltinData
v) (BuiltinList (BuiltinPair a BuiltinData) -> b
go BuiltinList (BuiltinPair a BuiltinData)
tl)
        )

makeLift ''Map