{-# LANGUAGE QuantifiedConstraints #-}

module Plutarch.Extra.Map (
  -- * Lookup
  ptryLookup,

  -- * Comparisons
  pkeysEqual,
  pkeysEqualUnsorted,

  -- * Modification
  pupdate,
  padjust,
  pmapWithKey,

  -- * Folds
  pfoldMapWithKey,
  pfoldlWithKey,

  -- * Conversion
  pkeys,

  -- * Key-value pair manipulation
  pkvPairKey,
  pkvPairValue,
  pkvPairLt,
) where

import Plutarch.Api.V1.AssocMap (
  KeyGuarantees (Sorted, Unsorted),
  PMap (PMap),
  plookup,
 )
import Plutarch.Builtin (ppairDataBuiltin)
import Plutarch.Extra.Maybe (passertPJust)
import qualified Plutarch.List as PList
import Plutarch.Prelude

{- | Like regular 'fmap' but it provides key of each element that is being
     modified.
-}
pmapWithKey ::
  forall (k :: PType) (a :: PType) (b :: PType) (keysort :: KeyGuarantees) (s :: S).
  (PIsData k, PIsData a, PIsData b) =>
  Term s ((k :--> a :--> b) :--> PMap keysort k a :--> PMap 'Unsorted k b)
pmapWithKey :: forall (k :: PType) (a :: PType) (b :: PType)
       (keysort :: KeyGuarantees) (s :: S).
(PIsData k, PIsData a, PIsData b) =>
Term
  s
  ((k :--> (a :--> b))
   :--> (PMap keysort k a :--> PMap 'Unsorted k b))
pmapWithKey = forall (a :: PType) (s :: S).
HasCallStack =>
ClosedTerm a -> Term s a
phoistAcyclic forall a b. (a -> b) -> a -> b
$
  forall a (b :: PType) (s :: S) (c :: PType).
(PLamN a b s, HasCallStack) =>
(Term s c -> a) -> Term s (c :--> b)
plam forall a b. (a -> b) -> a -> b
$ \Term s (k :--> (a :--> b))
f Term s (PMap keysort k a)
kvs ->
    forall (a :: PType) (s :: S) (b :: PType).
PlutusType a =>
Term s a -> (a s -> Term s b) -> Term s b
pmatch Term s (PMap keysort k a)
kvs forall a b. (a -> b) -> a -> b
$ \(PMap Term s (PBuiltinList (PBuiltinPair (PAsData k) (PAsData a)))
kvs') ->
      forall (a :: PType) (s :: S). PlutusType a => a s -> Term s a
pcon forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (keysort :: KeyGuarantees) (k :: PType) (v :: PType)
       (s :: S).
Term s (PBuiltinList (PBuiltinPair (PAsData k) (PAsData v)))
-> PMap keysort k v s
PMap forall a b. (a -> b) -> a -> b
$
        forall (list :: PType -> PType) (a :: PType) (b :: PType) (s :: S).
(PListLike list, PElemConstraint list a, PElemConstraint list b) =>
Term s ((a :--> b) :--> (list a :--> list b))
PList.pmap
          # plam
            ( \x ->
                plet (pkvPairKey # x) $ \key ->
                  ppairDataBuiltin
                    # pdata key
                    #$ pdata
                    $ f # key # (pkvPairValue # x)
            )
          # kvs'

{- | If a value exists at the specified key, apply the function argument to it;
 otherwise, do nothing.
-}
padjust ::
  forall (k :: PType) (v :: PType) (s :: S).
  (PIsData k, PEq k, PIsData v) =>
  Term s ((v :--> v) :--> k :--> PMap 'Unsorted k v :--> PMap 'Unsorted k v)
padjust :: forall (k :: PType) (v :: PType) (s :: S).
(PIsData k, PEq k, PIsData v) =>
Term
  s
  ((v :--> v)
   :--> (k :--> (PMap 'Unsorted k v :--> PMap 'Unsorted k v)))
padjust = forall (a :: PType) (s :: S).
HasCallStack =>
ClosedTerm a -> Term s a
phoistAcyclic forall a b. (a -> b) -> a -> b
$
  forall a (b :: PType) (s :: S) (c :: PType).
(PLamN a b s, HasCallStack) =>
(Term s c -> a) -> Term s (c :--> b)
plam forall a b. (a -> b) -> a -> b
$ \Term s (v :--> v)
f Term s k
key Term s (PMap 'Unsorted k v)
kvs ->
    forall (k :: PType) (a :: PType) (b :: PType)
       (keysort :: KeyGuarantees) (s :: S).
(PIsData k, PIsData a, PIsData b) =>
Term
  s
  ((k :--> (a :--> b))
   :--> (PMap keysort k a :--> PMap 'Unsorted k b))
pmapWithKey forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# forall a (b :: PType) (s :: S) (c :: PType).
(PLamN a b s, HasCallStack) =>
(Term s c -> a) -> Term s (c :--> b)
plam (\Term s k
k' Term s v
a -> forall (s :: S) (a :: PType).
Term s PBool -> Term s a -> Term s a -> Term s a
pif (Term s k
k' forall (t :: PType) (s :: S).
PEq t =>
Term s t -> Term s t -> Term s PBool
#== Term s k
key) (Term s (v :--> v)
f forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# Term s v
a) Term s v
a) forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# Term s (PMap 'Unsorted k v)
kvs

{- | As 'pkeysEqual', but requires only 'PEq' constraints for the keys, and
 works for 'Unsorted' 'PMap's. This requires a number of equality comparisons
 between keys proportional to the product of the lengths of both arguments:
 that is, this function is quadratic.
-}
pkeysEqualUnsorted ::
  forall (k :: PType) (a :: PType) (b :: PType) (s :: S).
  (PIsData k, PIsData a, PIsData b) =>
  Term s (PMap 'Unsorted k a :--> PMap 'Unsorted k b :--> PBool)
pkeysEqualUnsorted :: forall (k :: PType) (a :: PType) (b :: PType) (s :: S).
(PIsData k, PIsData a, PIsData b) =>
Term s (PMap 'Unsorted k a :--> (PMap 'Unsorted k b :--> PBool))
pkeysEqualUnsorted = forall (a :: PType) (s :: S).
HasCallStack =>
ClosedTerm a -> Term s a
phoistAcyclic forall a b. (a -> b) -> a -> b
$
  forall a (b :: PType) (s :: S) (c :: PType).
(PLamN a b s, HasCallStack) =>
(Term s c -> a) -> Term s (c :--> b)
plam forall a b. (a -> b) -> a -> b
$ \Term s (PMap 'Unsorted k a)
kvs Term s (PMap 'Unsorted k b)
kvs' ->
    forall (a :: PType) (s :: S) (b :: PType).
PlutusType a =>
Term s a -> (a s -> Term s b) -> Term s b
pmatch Term s (PMap 'Unsorted k a)
kvs forall a b. (a -> b) -> a -> b
$ \(PMap Term s (PBuiltinList (PBuiltinPair (PAsData k) (PAsData a)))
ell) ->
      forall (a :: PType) (s :: S) (b :: PType).
PlutusType a =>
Term s a -> (a s -> Term s b) -> Term s b
pmatch Term s (PMap 'Unsorted k b)
kvs' forall a b. (a -> b) -> a -> b
$ \(PMap Term s (PBuiltinList (PBuiltinPair (PAsData k) (PAsData b)))
ell') ->
        forall (s' :: S).
Term
  s'
  (PMap 'Unsorted k a
   :--> (PMap 'Unsorted k b
         :--> (PBuiltinList (PBuiltinPair (PAsData k) (PAsData a))
               :--> (PBuiltinList (PBuiltinPair (PAsData k) (PAsData b))
                     :--> PBool))))
go forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# Term s (PMap 'Unsorted k a)
kvs forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# Term s (PMap 'Unsorted k b)
kvs' forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# Term s (PBuiltinList (PBuiltinPair (PAsData k) (PAsData a)))
ell forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# Term s (PBuiltinList (PBuiltinPair (PAsData k) (PAsData b)))
ell'
  where
    go ::
      forall (s' :: S).
      Term
        s'
        ( PMap 'Unsorted k a
            :--> PMap 'Unsorted k b
            :--> PBuiltinList (PBuiltinPair (PAsData k) (PAsData a))
            :--> PBuiltinList (PBuiltinPair (PAsData k) (PAsData b))
            :--> PBool
        )
    go :: forall (s' :: S).
Term
  s'
  (PMap 'Unsorted k a
   :--> (PMap 'Unsorted k b
         :--> (PBuiltinList (PBuiltinPair (PAsData k) (PAsData a))
               :--> (PBuiltinList (PBuiltinPair (PAsData k) (PAsData b))
                     :--> PBool))))
go = forall (a :: PType) (s :: S).
HasCallStack =>
ClosedTerm a -> Term s a
phoistAcyclic forall a b. (a -> b) -> a -> b
$
      forall (s :: S) (a :: PType) (b :: PType).
Term s (((a :--> b) :--> (a :--> b)) :--> (a :--> b))
pfix forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
#$ forall a (b :: PType) (s :: S) (c :: PType).
(PLamN a b s, HasCallStack) =>
(Term s c -> a) -> Term s (c :--> b)
plam forall a b. (a -> b) -> a -> b
$ \Term
  s
  (PMap 'Unsorted k a
   :--> (PMap 'Unsorted k b
         :--> (PBuiltinList (PBuiltinPair (PAsData k) (PAsData a))
               :--> (PBuiltinList (PBuiltinPair (PAsData k) (PAsData b))
                     :--> PBool))))
self Term s (PMap 'Unsorted k a)
kvs Term s (PMap 'Unsorted k b)
kvs' Term s (PBuiltinList (PBuiltinPair (PAsData k) (PAsData a)))
ell Term s (PBuiltinList (PBuiltinPair (PAsData k) (PAsData b)))
ell' ->
        forall (a :: PType) (s :: S) (b :: PType).
PlutusType a =>
Term s a -> (a s -> Term s b) -> Term s b
pmatch (forall (list :: PType -> PType) (a :: PType) (s :: S).
PIsListLike list a =>
Term s (list a :--> PMaybe (PPair a (list a)))
PList.puncons forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# Term s (PBuiltinList (PBuiltinPair (PAsData k) (PAsData a)))
ell) forall a b. (a -> b) -> a -> b
$ \case
          PMaybe
  (PPair
     (PBuiltinPair (PAsData k) (PAsData a))
     (PBuiltinList (PBuiltinPair (PAsData k) (PAsData a))))
  s
PNothing -> forall (a :: PType) (s :: S) (b :: PType).
PlutusType a =>
Term s a -> (a s -> Term s b) -> Term s b
pmatch (forall (list :: PType -> PType) (a :: PType) (s :: S).
PIsListLike list a =>
Term s (list a :--> PMaybe (PPair a (list a)))
PList.puncons forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# Term s (PBuiltinList (PBuiltinPair (PAsData k) (PAsData b)))
ell') forall a b. (a -> b) -> a -> b
$ \case
            -- We reached the end, so we match
            PMaybe
  (PPair
     (PBuiltinPair (PAsData k) (PAsData b))
     (PBuiltinList (PBuiltinPair (PAsData k) (PAsData b))))
  s
PNothing -> forall (a :: PType) (s :: S). PlutusType a => a s -> Term s a
pcon forall (s :: S). PBool s
PTrue
            PJust Term
  s
  (PPair
     (PBuiltinPair (PAsData k) (PAsData b))
     (PBuiltinList (PBuiltinPair (PAsData k) (PAsData b))))
ht' -> forall (a :: PType) (s :: S) (b :: PType).
PlutusType a =>
Term s a -> (a s -> Term s b) -> Term s b
pmatch Term
  s
  (PPair
     (PBuiltinPair (PAsData k) (PAsData b))
     (PBuiltinList (PBuiltinPair (PAsData k) (PAsData b))))
ht' forall a b. (a -> b) -> a -> b
$ \(PPair Term s (PBuiltinPair (PAsData k) (PAsData b))
h' Term s (PBuiltinList (PBuiltinPair (PAsData k) (PAsData b)))
t') ->
              forall (a :: PType) (s :: S) (b :: PType).
PlutusType a =>
Term s a -> (a s -> Term s b) -> Term s b
pmatch (forall (k :: PType) (v :: PType) (s :: S) (any :: KeyGuarantees).
(PIsData k, PIsData v) =>
Term s (k :--> (PMap any k v :--> PMaybe v))
plookup forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# (forall (k :: PType) (v :: PType) (s :: S).
PIsData k =>
Term s (PBuiltinPair (PAsData k) (PAsData v) :--> k)
pkvPairKey forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# Term s (PBuiltinPair (PAsData k) (PAsData b))
h') forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# Term s (PMap 'Unsorted k a)
kvs) forall a b. (a -> b) -> a -> b
$ \case
                -- We mismatch, so fail
                PMaybe a s
PNothing -> forall (a :: PType) (s :: S). PlutusType a => a s -> Term s a
pcon forall (s :: S). PBool s
PFalse
                -- We match, so continue
                PJust Term s a
_ -> Term
  s
  (PMap 'Unsorted k a
   :--> (PMap 'Unsorted k b
         :--> (PBuiltinList (PBuiltinPair (PAsData k) (PAsData a))
               :--> (PBuiltinList (PBuiltinPair (PAsData k) (PAsData b))
                     :--> PBool))))
self forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# Term s (PMap 'Unsorted k a)
kvs forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# Term s (PMap 'Unsorted k b)
kvs' forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# Term s (PBuiltinList (PBuiltinPair (PAsData k) (PAsData a)))
ell forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# Term s (PBuiltinList (PBuiltinPair (PAsData k) (PAsData b)))
t'
          PJust Term
  s
  (PPair
     (PBuiltinPair (PAsData k) (PAsData a))
     (PBuiltinList (PBuiltinPair (PAsData k) (PAsData a))))
ht -> forall (a :: PType) (s :: S) (b :: PType).
PlutusType a =>
Term s a -> (a s -> Term s b) -> Term s b
pmatch Term
  s
  (PPair
     (PBuiltinPair (PAsData k) (PAsData a))
     (PBuiltinList (PBuiltinPair (PAsData k) (PAsData a))))
ht forall a b. (a -> b) -> a -> b
$ \(PPair Term s (PBuiltinPair (PAsData k) (PAsData a))
h Term s (PBuiltinList (PBuiltinPair (PAsData k) (PAsData a)))
t) ->
            forall (a :: PType) (s :: S) (b :: PType).
PlutusType a =>
Term s a -> (a s -> Term s b) -> Term s b
pmatch (forall (list :: PType -> PType) (a :: PType) (s :: S).
PIsListLike list a =>
Term s (list a :--> PMaybe (PPair a (list a)))
PList.puncons forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# Term s (PBuiltinList (PBuiltinPair (PAsData k) (PAsData b)))
ell') forall a b. (a -> b) -> a -> b
$ \case
              PMaybe
  (PPair
     (PBuiltinPair (PAsData k) (PAsData b))
     (PBuiltinList (PBuiltinPair (PAsData k) (PAsData b))))
  s
PNothing -> forall (a :: PType) (s :: S) (b :: PType).
PlutusType a =>
Term s a -> (a s -> Term s b) -> Term s b
pmatch (forall (k :: PType) (v :: PType) (s :: S) (any :: KeyGuarantees).
(PIsData k, PIsData v) =>
Term s (k :--> (PMap any k v :--> PMaybe v))
plookup forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# (forall (k :: PType) (v :: PType) (s :: S).
PIsData k =>
Term s (PBuiltinPair (PAsData k) (PAsData v) :--> k)
pkvPairKey forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# Term s (PBuiltinPair (PAsData k) (PAsData a))
h) forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# Term s (PMap 'Unsorted k b)
kvs') forall a b. (a -> b) -> a -> b
$ \case
                -- We mismatch, so fail
                PMaybe b s
PNothing -> forall (a :: PType) (s :: S). PlutusType a => a s -> Term s a
pcon forall (s :: S). PBool s
PFalse
                -- We match, so continue
                PJust Term s b
_ -> Term
  s
  (PMap 'Unsorted k a
   :--> (PMap 'Unsorted k b
         :--> (PBuiltinList (PBuiltinPair (PAsData k) (PAsData a))
               :--> (PBuiltinList (PBuiltinPair (PAsData k) (PAsData b))
                     :--> PBool))))
self forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# Term s (PMap 'Unsorted k a)
kvs forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# Term s (PMap 'Unsorted k b)
kvs' forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# Term s (PBuiltinList (PBuiltinPair (PAsData k) (PAsData a)))
t forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# Term s (PBuiltinList (PBuiltinPair (PAsData k) (PAsData b)))
ell'
              -- To save some effort, we try both matches in one shot
              PJust Term
  s
  (PPair
     (PBuiltinPair (PAsData k) (PAsData b))
     (PBuiltinList (PBuiltinPair (PAsData k) (PAsData b))))
ht' -> forall (a :: PType) (s :: S) (b :: PType).
PlutusType a =>
Term s a -> (a s -> Term s b) -> Term s b
pmatch Term
  s
  (PPair
     (PBuiltinPair (PAsData k) (PAsData b))
     (PBuiltinList (PBuiltinPair (PAsData k) (PAsData b))))
ht' forall a b. (a -> b) -> a -> b
$ \(PPair Term s (PBuiltinPair (PAsData k) (PAsData b))
h' Term s (PBuiltinList (PBuiltinPair (PAsData k) (PAsData b)))
t') ->
                forall (a :: PType) (s :: S) (b :: PType).
PlutusType a =>
Term s a -> (a s -> Term s b) -> Term s b
pmatch (forall (k :: PType) (v :: PType) (s :: S) (any :: KeyGuarantees).
(PIsData k, PIsData v) =>
Term s (k :--> (PMap any k v :--> PMaybe v))
plookup forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# (forall (k :: PType) (v :: PType) (s :: S).
PIsData k =>
Term s (PBuiltinPair (PAsData k) (PAsData v) :--> k)
pkvPairKey forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# Term s (PBuiltinPair (PAsData k) (PAsData a))
h) forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# Term s (PMap 'Unsorted k b)
kvs') forall a b. (a -> b) -> a -> b
$ \case
                  -- We mismatch, so fail
                  PMaybe b s
PNothing -> forall (a :: PType) (s :: S). PlutusType a => a s -> Term s a
pcon forall (s :: S). PBool s
PFalse
                  -- Try the other direction
                  PJust Term s b
_ -> forall (a :: PType) (s :: S) (b :: PType).
PlutusType a =>
Term s a -> (a s -> Term s b) -> Term s b
pmatch (forall (k :: PType) (v :: PType) (s :: S) (any :: KeyGuarantees).
(PIsData k, PIsData v) =>
Term s (k :--> (PMap any k v :--> PMaybe v))
plookup forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# (forall (k :: PType) (v :: PType) (s :: S).
PIsData k =>
Term s (PBuiltinPair (PAsData k) (PAsData v) :--> k)
pkvPairKey forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# Term s (PBuiltinPair (PAsData k) (PAsData b))
h') forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# Term s (PMap 'Unsorted k a)
kvs) forall a b. (a -> b) -> a -> b
$ \case
                    -- We mismatch, so fail
                    PMaybe a s
PNothing -> forall (a :: PType) (s :: S). PlutusType a => a s -> Term s a
pcon forall (s :: S). PBool s
PFalse
                    -- Both succeeded, so continue on tails
                    PJust Term s a
_ -> Term
  s
  (PMap 'Unsorted k a
   :--> (PMap 'Unsorted k b
         :--> (PBuiltinList (PBuiltinPair (PAsData k) (PAsData a))
               :--> (PBuiltinList (PBuiltinPair (PAsData k) (PAsData b))
                     :--> PBool))))
self forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# Term s (PMap 'Unsorted k a)
kvs forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# Term s (PMap 'Unsorted k b)
kvs' forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# Term s (PBuiltinList (PBuiltinPair (PAsData k) (PAsData a)))
t forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# Term s (PBuiltinList (PBuiltinPair (PAsData k) (PAsData b)))
t'

{- | Gives 'PTrue' if both argument 'PMap's contain mappings for exactly the
 same set of keys. Requires a number of equality comparisons between keys
 proportional to the length of the shorter argument.
-}
pkeysEqual ::
  forall (k :: PType) (a :: PType) (b :: PType) (s :: S).
  (PIsData k, PEq k) =>
  Term s (PMap 'Sorted k a :--> PMap 'Sorted k b :--> PBool)
pkeysEqual :: forall (k :: PType) (a :: PType) (b :: PType) (s :: S).
(PIsData k, PEq k) =>
Term s (PMap 'Sorted k a :--> (PMap 'Sorted k b :--> PBool))
pkeysEqual = forall (a :: PType) (s :: S).
HasCallStack =>
ClosedTerm a -> Term s a
phoistAcyclic forall a b. (a -> b) -> a -> b
$
  forall a (b :: PType) (s :: S) (c :: PType).
(PLamN a b s, HasCallStack) =>
(Term s c -> a) -> Term s (c :--> b)
plam forall a b. (a -> b) -> a -> b
$ \Term s (PMap 'Sorted k a)
kvs Term s (PMap 'Sorted k b)
kvs' ->
    forall (a :: PType) (s :: S) (b :: PType).
PlutusType a =>
Term s a -> (a s -> Term s b) -> Term s b
pmatch Term s (PMap 'Sorted k a)
kvs forall a b. (a -> b) -> a -> b
$ \(PMap Term s (PBuiltinList (PBuiltinPair (PAsData k) (PAsData a)))
ell) ->
      forall (a :: PType) (s :: S) (b :: PType).
PlutusType a =>
Term s a -> (a s -> Term s b) -> Term s b
pmatch Term s (PMap 'Sorted k b)
kvs' forall a b. (a -> b) -> a -> b
$ \(PMap Term s (PBuiltinList (PBuiltinPair (PAsData k) (PAsData b)))
ell') ->
        forall (s' :: S).
Term
  s'
  (PBuiltinList (PBuiltinPair (PAsData k) (PAsData a))
   :--> (PBuiltinList (PBuiltinPair (PAsData k) (PAsData b))
         :--> PBool))
go forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# Term s (PBuiltinList (PBuiltinPair (PAsData k) (PAsData a)))
ell forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# Term s (PBuiltinList (PBuiltinPair (PAsData k) (PAsData b)))
ell'
  where
    go ::
      forall (s' :: S).
      Term
        s'
        ( PBuiltinList (PBuiltinPair (PAsData k) (PAsData a))
            :--> PBuiltinList (PBuiltinPair (PAsData k) (PAsData b))
            :--> PBool
        )
    go :: forall (s' :: S).
Term
  s'
  (PBuiltinList (PBuiltinPair (PAsData k) (PAsData a))
   :--> (PBuiltinList (PBuiltinPair (PAsData k) (PAsData b))
         :--> PBool))
go = forall (a :: PType) (s :: S).
HasCallStack =>
ClosedTerm a -> Term s a
phoistAcyclic forall a b. (a -> b) -> a -> b
$
      forall (s :: S) (a :: PType) (b :: PType).
Term s (((a :--> b) :--> (a :--> b)) :--> (a :--> b))
pfix forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
#$ forall a (b :: PType) (s :: S) (c :: PType).
(PLamN a b s, HasCallStack) =>
(Term s c -> a) -> Term s (c :--> b)
plam forall a b. (a -> b) -> a -> b
$ \Term
  s
  (PBuiltinList (PBuiltinPair (PAsData k) (PAsData a))
   :--> (PBuiltinList (PBuiltinPair (PAsData k) (PAsData b))
         :--> PBool))
self Term s (PBuiltinList (PBuiltinPair (PAsData k) (PAsData a)))
ell Term s (PBuiltinList (PBuiltinPair (PAsData k) (PAsData b)))
ell' ->
        forall (a :: PType) (s :: S) (b :: PType).
PlutusType a =>
Term s a -> (a s -> Term s b) -> Term s b
pmatch (forall (list :: PType -> PType) (a :: PType) (s :: S).
PIsListLike list a =>
Term s (list a :--> PMaybe (PPair a (list a)))
PList.puncons forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# Term s (PBuiltinList (PBuiltinPair (PAsData k) (PAsData a)))
ell) forall a b. (a -> b) -> a -> b
$ \case
          PMaybe
  (PPair
     (PBuiltinPair (PAsData k) (PAsData a))
     (PBuiltinList (PBuiltinPair (PAsData k) (PAsData a))))
  s
PNothing -> forall (a :: PType) (s :: S) (b :: PType).
PlutusType a =>
Term s a -> (a s -> Term s b) -> Term s b
pmatch (forall (list :: PType -> PType) (a :: PType) (s :: S).
PIsListLike list a =>
Term s (list a :--> PMaybe (PPair a (list a)))
PList.puncons forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# Term s (PBuiltinList (PBuiltinPair (PAsData k) (PAsData b)))
ell') forall a b. (a -> b) -> a -> b
$ \case
            PMaybe
  (PPair
     (PBuiltinPair (PAsData k) (PAsData b))
     (PBuiltinList (PBuiltinPair (PAsData k) (PAsData b))))
  s
PNothing -> forall (a :: PType) (s :: S). PlutusType a => a s -> Term s a
pcon forall (s :: S). PBool s
PTrue -- no mismatches found
            PJust Term
  s
  (PPair
     (PBuiltinPair (PAsData k) (PAsData b))
     (PBuiltinList (PBuiltinPair (PAsData k) (PAsData b))))
_ -> forall (a :: PType) (s :: S). PlutusType a => a s -> Term s a
pcon forall (s :: S). PBool s
PFalse -- one argument too long
          PJust Term
  s
  (PPair
     (PBuiltinPair (PAsData k) (PAsData a))
     (PBuiltinList (PBuiltinPair (PAsData k) (PAsData a))))
kv -> forall (a :: PType) (s :: S) (b :: PType).
PlutusType a =>
Term s a -> (a s -> Term s b) -> Term s b
pmatch (forall (list :: PType -> PType) (a :: PType) (s :: S).
PIsListLike list a =>
Term s (list a :--> PMaybe (PPair a (list a)))
PList.puncons forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# Term s (PBuiltinList (PBuiltinPair (PAsData k) (PAsData b)))
ell') forall a b. (a -> b) -> a -> b
$ \case
            PMaybe
  (PPair
     (PBuiltinPair (PAsData k) (PAsData b))
     (PBuiltinList (PBuiltinPair (PAsData k) (PAsData b))))
  s
PNothing -> forall (a :: PType) (s :: S). PlutusType a => a s -> Term s a
pcon forall (s :: S). PBool s
PFalse -- one argument too long
            PJust Term
  s
  (PPair
     (PBuiltinPair (PAsData k) (PAsData b))
     (PBuiltinList (PBuiltinPair (PAsData k) (PAsData b))))
kv' -> forall (a :: PType) (s :: S) (b :: PType).
PlutusType a =>
Term s a -> (a s -> Term s b) -> Term s b
pmatch Term
  s
  (PPair
     (PBuiltinPair (PAsData k) (PAsData a))
     (PBuiltinList (PBuiltinPair (PAsData k) (PAsData a))))
kv forall a b. (a -> b) -> a -> b
$ \(PPair Term s (PBuiltinPair (PAsData k) (PAsData a))
h Term s (PBuiltinList (PBuiltinPair (PAsData k) (PAsData a)))
t) ->
              forall (a :: PType) (s :: S) (b :: PType).
PlutusType a =>
Term s a -> (a s -> Term s b) -> Term s b
pmatch Term
  s
  (PPair
     (PBuiltinPair (PAsData k) (PAsData b))
     (PBuiltinList (PBuiltinPair (PAsData k) (PAsData b))))
kv' forall a b. (a -> b) -> a -> b
$ \(PPair Term s (PBuiltinPair (PAsData k) (PAsData b))
h' Term s (PBuiltinList (PBuiltinPair (PAsData k) (PAsData b)))
t') ->
                forall (s :: S) (a :: PType).
Term s PBool -> Term s a -> Term s a -> Term s a
pif
                  ((forall (k :: PType) (v :: PType) (s :: S).
PIsData k =>
Term s (PBuiltinPair (PAsData k) (PAsData v) :--> k)
pkvPairKey forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# Term s (PBuiltinPair (PAsData k) (PAsData a))
h) forall (t :: PType) (s :: S).
PEq t =>
Term s t -> Term s t -> Term s PBool
#== (forall (k :: PType) (v :: PType) (s :: S).
PIsData k =>
Term s (PBuiltinPair (PAsData k) (PAsData v) :--> k)
pkvPairKey forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# Term s (PBuiltinPair (PAsData k) (PAsData b))
h'))
                  (Term
  s
  (PBuiltinList (PBuiltinPair (PAsData k) (PAsData a))
   :--> (PBuiltinList (PBuiltinPair (PAsData k) (PAsData b))
         :--> PBool))
self forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# Term s (PBuiltinList (PBuiltinPair (PAsData k) (PAsData a)))
t forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# Term s (PBuiltinList (PBuiltinPair (PAsData k) (PAsData b)))
t') -- continue
                  (forall (a :: PType) (s :: S). PlutusType a => a s -> Term s a
pcon forall (s :: S). PBool s
PFalse) -- key mismatch

-- | Get the key of a key-value pair.
pkvPairKey ::
  forall (k :: PType) (v :: PType) (s :: S).
  (PIsData k) =>
  Term s (PBuiltinPair (PAsData k) (PAsData v) :--> k)
pkvPairKey :: forall (k :: PType) (v :: PType) (s :: S).
PIsData k =>
Term s (PBuiltinPair (PAsData k) (PAsData v) :--> k)
pkvPairKey = forall (a :: PType) (s :: S).
HasCallStack =>
ClosedTerm a -> Term s a
phoistAcyclic forall a b. (a -> b) -> a -> b
$ forall a (b :: PType) (s :: S) (c :: PType).
(PLamN a b s, HasCallStack) =>
(Term s c -> a) -> Term s (c :--> b)
plam forall a b. (a -> b) -> a -> b
$ \Term s (PBuiltinPair (PAsData k) (PAsData v))
kv -> forall (a :: PType) (s :: S).
PIsData a =>
Term s (PAsData a) -> Term s a
pfromData (forall (s :: S) (a :: PType) (b :: PType).
Term s (PBuiltinPair a b :--> a)
pfstBuiltin forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# Term s (PBuiltinPair (PAsData k) (PAsData v))
kv)

-- | Get the value of a key-value pair.
pkvPairValue ::
  forall (k :: PType) (v :: PType) (s :: S).
  (PIsData v) =>
  Term s (PBuiltinPair (PAsData k) (PAsData v) :--> v)
pkvPairValue :: forall (k :: PType) (v :: PType) (s :: S).
PIsData v =>
Term s (PBuiltinPair (PAsData k) (PAsData v) :--> v)
pkvPairValue = forall (a :: PType) (s :: S).
HasCallStack =>
ClosedTerm a -> Term s a
phoistAcyclic forall a b. (a -> b) -> a -> b
$ forall a (b :: PType) (s :: S) (c :: PType).
(PLamN a b s, HasCallStack) =>
(Term s c -> a) -> Term s (c :--> b)
plam forall a b. (a -> b) -> a -> b
$ \Term s (PBuiltinPair (PAsData k) (PAsData v))
kv -> forall (a :: PType) (s :: S).
PIsData a =>
Term s (PAsData a) -> Term s a
pfromData (forall (s :: S) (a :: PType) (b :: PType).
Term s (PBuiltinPair a b :--> b)
psndBuiltin forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# Term s (PBuiltinPair (PAsData k) (PAsData v))
kv)

{- | Compare two key-value pairs by their keys. Gives 'PTrue' if the key of the
 first argument pair is less than the key of the second argument pair.
-}
pkvPairLt ::
  forall (k :: PType) (v :: PType) (s :: S).
  (PIsData k, PPartialOrd k) =>
  Term
    s
    ( PBuiltinPair (PAsData k) (PAsData v)
        :--> PBuiltinPair (PAsData k) (PAsData v)
        :--> PBool
    )
pkvPairLt :: forall (k :: PType) (v :: PType) (s :: S).
(PIsData k, PPartialOrd k) =>
Term
  s
  (PBuiltinPair (PAsData k) (PAsData v)
   :--> (PBuiltinPair (PAsData k) (PAsData v) :--> PBool))
pkvPairLt = forall (a :: PType) (s :: S).
HasCallStack =>
ClosedTerm a -> Term s a
phoistAcyclic forall a b. (a -> b) -> a -> b
$
  forall a (b :: PType) (s :: S) (c :: PType).
(PLamN a b s, HasCallStack) =>
(Term s c -> a) -> Term s (c :--> b)
plam forall a b. (a -> b) -> a -> b
$ \Term s (PBuiltinPair (PAsData k) (PAsData v))
kv Term s (PBuiltinPair (PAsData k) (PAsData v))
kv' ->
    (forall (k :: PType) (v :: PType) (s :: S).
PIsData k =>
Term s (PBuiltinPair (PAsData k) (PAsData v) :--> k)
pkvPairKey forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# Term s (PBuiltinPair (PAsData k) (PAsData v))
kv) forall (t :: PType) (s :: S).
PPartialOrd t =>
Term s t -> Term s t -> Term s PBool
#< (forall (k :: PType) (v :: PType) (s :: S).
PIsData k =>
Term s (PBuiltinPair (PAsData k) (PAsData v) :--> k)
pkvPairKey forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# Term s (PBuiltinPair (PAsData k) (PAsData v))
kv')

-- | As 'plookup', but errors when the key is missing.
ptryLookup ::
  forall (k :: PType) (v :: PType) (keys :: KeyGuarantees) (s :: S).
  (PIsData k, PIsData v) =>
  Term s (k :--> PMap keys k v :--> v)
ptryLookup :: forall (k :: PType) (v :: PType) (keys :: KeyGuarantees) (s :: S).
(PIsData k, PIsData v) =>
Term s (k :--> (PMap keys k v :--> v))
ptryLookup = forall (a :: PType) (s :: S).
HasCallStack =>
ClosedTerm a -> Term s a
phoistAcyclic forall a b. (a -> b) -> a -> b
$
  forall a (b :: PType) (s :: S) (c :: PType).
(PLamN a b s, HasCallStack) =>
(Term s c -> a) -> Term s (c :--> b)
plam forall a b. (a -> b) -> a -> b
$ \Term s k
k Term s (PMap keys k v)
kvs ->
    forall (a :: PType) (s :: S).
Term s (PString :--> (PMaybe a :--> a))
passertPJust
      # "plookupPartial: No value found for key."
      # (plookup # k # kvs)

{- | Get a list-like structure full of the keys of the argument 'PMap'. If the
 'PMap' is 'Sorted', the keys will maintain that order, and will be unique;
 otherwise, the order is unspecified, and duplicates may exist.

 = Note

 You will need to specify what manner of list-like structure you want; we have
 arranged the type signature to make specifying this easy with
 @TypeApplications@.
-}
pkeys ::
  forall
    (ell :: PType -> PType)
    (k :: PType)
    (v :: PType)
    (keys :: KeyGuarantees)
    (s :: S).
  (PListLike ell, PElemConstraint ell (PAsData k)) =>
  Term s (PMap keys k v :--> ell (PAsData k))
pkeys :: forall (ell :: PType -> PType) (k :: PType) (v :: PType)
       (keys :: KeyGuarantees) (s :: S).
(PListLike ell, PElemConstraint ell (PAsData k)) =>
Term s (PMap keys k v :--> ell (PAsData k))
pkeys = forall (a :: PType) (s :: S).
HasCallStack =>
ClosedTerm a -> Term s a
phoistAcyclic forall a b. (a -> b) -> a -> b
$
  forall a (b :: PType) (s :: S) (c :: PType).
(PLamN a b s, HasCallStack) =>
(Term s c -> a) -> Term s (c :--> b)
plam forall a b. (a -> b) -> a -> b
$ \Term s (PMap keys k v)
kvs -> forall (a :: PType) (s :: S) (b :: PType).
PlutusType a =>
Term s a -> (a s -> Term s b) -> Term s b
pmatch Term s (PMap keys k v)
kvs forall a b. (a -> b) -> a -> b
$ \(PMap Term s (PBuiltinList (PBuiltinPair (PAsData k) (PAsData v)))
kvs') ->
    forall (list :: PType -> PType) (a :: PType) (s :: S) (r :: PType).
PIsListLike list a =>
(Term s (list a :--> r) -> Term s a -> Term s (list a) -> Term s r)
-> (Term s (list a :--> r) -> Term s r) -> Term s (list a :--> r)
precList forall (s' :: S).
Term
  s'
  (PBuiltinList (PBuiltinPair (PAsData k) (PAsData v))
   :--> ell (PAsData k))
-> Term s' (PBuiltinPair (PAsData k) (PAsData v))
-> Term s' (PBuiltinList (PBuiltinPair (PAsData k) (PAsData v)))
-> Term s' (ell (PAsData k))
go (forall a b. a -> b -> a
const forall (list :: PType -> PType) (a :: PType) (s :: S).
(PListLike list, PElemConstraint list a) =>
Term s (list a)
pnil) forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# Term s (PBuiltinList (PBuiltinPair (PAsData k) (PAsData v)))
kvs'
  where
    go ::
      forall (s' :: S).
      Term s' (PBuiltinList (PBuiltinPair (PAsData k) (PAsData v)) :--> ell (PAsData k)) ->
      Term s' (PBuiltinPair (PAsData k) (PAsData v)) ->
      Term s' (PBuiltinList (PBuiltinPair (PAsData k) (PAsData v))) ->
      Term s' (ell (PAsData k))
    go :: forall (s' :: S).
Term
  s'
  (PBuiltinList (PBuiltinPair (PAsData k) (PAsData v))
   :--> ell (PAsData k))
-> Term s' (PBuiltinPair (PAsData k) (PAsData v))
-> Term s' (PBuiltinList (PBuiltinPair (PAsData k) (PAsData v)))
-> Term s' (ell (PAsData k))
go Term
  s'
  (PBuiltinList (PBuiltinPair (PAsData k) (PAsData v))
   :--> ell (PAsData k))
self Term s' (PBuiltinPair (PAsData k) (PAsData v))
kv Term s' (PBuiltinList (PBuiltinPair (PAsData k) (PAsData v)))
acc = forall (list :: PType -> PType) (a :: PType) (s :: S).
(PListLike list, PElemConstraint list a) =>
Term s (a :--> (list a :--> list a))
pcons forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# (forall (s :: S) (a :: PType) (b :: PType).
Term s (PBuiltinPair a b :--> a)
pfstBuiltin forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# Term s' (PBuiltinPair (PAsData k) (PAsData v))
kv) forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# (Term
  s'
  (PBuiltinList (PBuiltinPair (PAsData k) (PAsData v))
   :--> ell (PAsData k))
self forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# Term s' (PBuiltinList (PBuiltinPair (PAsData k) (PAsData v)))
acc)

{- | Given an \'updater\' and a key, if the key exists in the 'PMap', apply the
 \'updater\' to it, otherwise do nothing. If the \'updater\' produces
 'PNothing', the value is deleted; otherwise, it is modified to the result.

 Performance will be equivalent to a lookup followed by an insert (or delete),
 as well as the cost of calling the \'updater\'.
-}
pupdate ::
  forall (k :: PType) (v :: PType) (s :: S).
  (PIsData k, PIsData v, POrd k) =>
  Term s ((v :--> PMaybe v) :--> k :--> PMap 'Sorted k v :--> PMap 'Sorted k v)
pupdate :: forall (k :: PType) (v :: PType) (s :: S).
(PIsData k, PIsData v, POrd k) =>
Term
  s
  ((v :--> PMaybe v)
   :--> (k :--> (PMap 'Sorted k v :--> PMap 'Sorted k v)))
pupdate = forall (a :: PType) (s :: S).
HasCallStack =>
ClosedTerm a -> Term s a
phoistAcyclic forall a b. (a -> b) -> a -> b
$
  forall a (b :: PType) (s :: S) (c :: PType).
(PLamN a b s, HasCallStack) =>
(Term s c -> a) -> Term s (c :--> b)
plam forall a b. (a -> b) -> a -> b
$ \Term s (v :--> PMaybe v)
updater Term s k
key Term s (PMap 'Sorted k v)
kvs -> forall (a :: PType) (s :: S) (b :: PType).
PlutusType a =>
Term s a -> (a s -> Term s b) -> Term s b
pmatch Term s (PMap 'Sorted k v)
kvs forall a b. (a -> b) -> a -> b
$ \(PMap Term s (PBuiltinList (PBuiltinPair (PAsData k) (PAsData v)))
kvs') ->
    forall (a :: PType) (s :: S). PlutusType a => a s -> Term s a
pcon forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (keysort :: KeyGuarantees) (k :: PType) (v :: PType)
       (s :: S).
Term s (PBuiltinList (PBuiltinPair (PAsData k) (PAsData v)))
-> PMap keysort k v s
PMap forall a b. (a -> b) -> a -> b
$
      ( forall (list :: PType -> PType) (a :: PType) (s :: S) (r :: PType).
PIsListLike list a =>
(Term s (list a :--> r) -> Term s a -> Term s (list a) -> Term s r)
-> (Term s (list a :--> r) -> Term s r) -> Term s (list a :--> r)
precList
          ( \Term
  s
  (PBuiltinList (PBuiltinPair (PAsData k) (PAsData v))
   :--> PBuiltinList (PBuiltinPair (PAsData k) (PAsData v)))
self Term s (PBuiltinPair (PAsData k) (PAsData v))
x Term s (PBuiltinList (PBuiltinPair (PAsData k) (PAsData v)))
xs ->
              forall (s :: S) (a :: PType) (b :: PType).
Term s a -> (Term s a -> Term s b) -> Term s b
plet (forall (a :: PType) (s :: S).
PIsData a =>
Term s (PAsData a) -> Term s a
pfromData forall a b. (a -> b) -> a -> b
$ forall (s :: S) (a :: PType) (b :: PType).
Term s (PBuiltinPair a b :--> a)
pfstBuiltin forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# Term s (PBuiltinPair (PAsData k) (PAsData v))
x) forall a b. (a -> b) -> a -> b
$ \Term s k
k ->
                forall (s :: S) (a :: PType).
Term s PBool -> Term s a -> Term s a -> Term s a
pif
                  (Term s k
k forall (t :: PType) (s :: S).
PEq t =>
Term s t -> Term s t -> Term s PBool
#== Term s k
key)
                  ( forall (a :: PType) (s :: S) (b :: PType).
PlutusType a =>
Term s a -> (a s -> Term s b) -> Term s b
pmatch (Term s (v :--> PMaybe v)
updater forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# forall (a :: PType) (s :: S).
PIsData a =>
Term s (PAsData a) -> Term s a
pfromData (forall (s :: S) (a :: PType) (b :: PType).
Term s (PBuiltinPair a b :--> b)
psndBuiltin forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# Term s (PBuiltinPair (PAsData k) (PAsData v))
x)) forall a b. (a -> b) -> a -> b
$ \case
                      PMaybe v s
PNothing -> Term
  s
  (PBuiltinList (PBuiltinPair (PAsData k) (PAsData v))
   :--> PBuiltinList (PBuiltinPair (PAsData k) (PAsData v)))
self forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# Term s (PBuiltinList (PBuiltinPair (PAsData k) (PAsData v)))
xs
                      PJust Term s v
v -> forall (list :: PType -> PType) (a :: PType) (s :: S).
(PListLike list, PElemConstraint list a) =>
Term s (a :--> (list a :--> list a))
pcons forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# (forall (s :: S) (a :: PType) (b :: PType).
Term
  s
  (PAsData a
   :--> (PAsData b :--> PBuiltinPair (PAsData a) (PAsData b)))
ppairDataBuiltin forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# forall (a :: PType) (s :: S).
PIsData a =>
Term s a -> Term s (PAsData a)
pdata Term s k
k forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# forall (a :: PType) (s :: S).
PIsData a =>
Term s a -> Term s (PAsData a)
pdata Term s v
v) forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
#$ Term
  s
  (PBuiltinList (PBuiltinPair (PAsData k) (PAsData v))
   :--> PBuiltinList (PBuiltinPair (PAsData k) (PAsData v)))
self forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# Term s (PBuiltinList (PBuiltinPair (PAsData k) (PAsData v)))
xs
                  )
                  (forall (s :: S) (a :: PType).
Term s PBool -> Term s a -> Term s a -> Term s a
pif (Term s k
key forall (t :: PType) (s :: S).
PPartialOrd t =>
Term s t -> Term s t -> Term s PBool
#<= Term s k
k) (forall (list :: PType -> PType) (a :: PType) (s :: S).
(PListLike list, PElemConstraint list a) =>
Term s (a :--> (list a :--> list a))
pcons forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# Term s (PBuiltinPair (PAsData k) (PAsData v))
x forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# Term s (PBuiltinList (PBuiltinPair (PAsData k) (PAsData v)))
xs) (forall (list :: PType -> PType) (a :: PType) (s :: S).
(PListLike list, PElemConstraint list a) =>
Term s (a :--> (list a :--> list a))
pcons forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# Term s (PBuiltinPair (PAsData k) (PAsData v))
x forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
#$ Term
  s
  (PBuiltinList (PBuiltinPair (PAsData k) (PAsData v))
   :--> PBuiltinList (PBuiltinPair (PAsData k) (PAsData v)))
self forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# Term s (PBuiltinList (PBuiltinPair (PAsData k) (PAsData v)))
xs))
          )
          (forall a b. a -> b -> a
const forall (list :: PType -> PType) (a :: PType) (s :: S).
(PListLike list, PElemConstraint list a) =>
Term s (list a)
pnil)
          # kvs'
      )

{- | Left-associative fold of a 'PMap' with keys. Keys and values will be
 presented in key order.
-}
pfoldlWithKey ::
  forall (a :: PType) (k :: PType) (v :: PType) (s :: S).
  (PIsData k, PIsData v) =>
  Term s ((a :--> k :--> v :--> a) :--> a :--> PMap 'Sorted k v :--> a)
pfoldlWithKey :: forall (a :: PType) (k :: PType) (v :: PType) (s :: S).
(PIsData k, PIsData v) =>
Term
  s
  ((a :--> (k :--> (v :--> a)))
   :--> (a :--> (PMap 'Sorted k v :--> a)))
pfoldlWithKey = forall (a :: PType) (s :: S).
HasCallStack =>
ClosedTerm a -> Term s a
phoistAcyclic forall a b. (a -> b) -> a -> b
$
  forall a (b :: PType) (s :: S) (c :: PType).
(PLamN a b s, HasCallStack) =>
(Term s c -> a) -> Term s (c :--> b)
plam forall a b. (a -> b) -> a -> b
$ \Term s (a :--> (k :--> (v :--> a)))
f Term s a
x Term s (PMap 'Sorted k v)
kvs -> forall (a :: PType) (s :: S) (b :: PType).
PlutusType a =>
Term s a -> (a s -> Term s b) -> Term s b
pmatch Term s (PMap 'Sorted k v)
kvs forall a b. (a -> b) -> a -> b
$ \case
    PMap Term s (PBuiltinList (PBuiltinPair (PAsData k) (PAsData v)))
kvs' ->
      forall (list :: PType -> PType) (a :: PType) (s :: S) (b :: PType).
PIsListLike list a =>
Term s ((b :--> (a :--> b)) :--> (b :--> (list a :--> b)))
pfoldl forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# forall a (b :: PType) (s :: S) (c :: PType).
(PLamN a b s, HasCallStack) =>
(Term s c -> a) -> Term s (c :--> b)
plam (\Term s a
acc Term s (PBuiltinPair (PAsData k) (PAsData v))
kv -> Term s (a :--> (k :--> (v :--> a)))
f forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# Term s a
acc forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# (forall (k :: PType) (v :: PType) (s :: S).
PIsData k =>
Term s (PBuiltinPair (PAsData k) (PAsData v) :--> k)
pkvPairKey forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# Term s (PBuiltinPair (PAsData k) (PAsData v))
kv) forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# (forall (k :: PType) (v :: PType) (s :: S).
PIsData v =>
Term s (PBuiltinPair (PAsData k) (PAsData v) :--> v)
pkvPairValue forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# Term s (PBuiltinPair (PAsData k) (PAsData v))
kv)) forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# Term s a
x forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# Term s (PBuiltinList (PBuiltinPair (PAsData k) (PAsData v)))
kvs'

{- | Project all key-value pairs into a 'Monoid', then combine. Keys and values
 will be presented in key order.
-}
pfoldMapWithKey ::
  forall (m :: PType) (k :: PType) (v :: PType) (s :: S).
  (PIsData k, PIsData v, forall (s' :: S). Monoid (Term s' m)) =>
  Term s ((k :--> v :--> m) :--> PMap 'Sorted k v :--> m)
pfoldMapWithKey :: forall (m :: PType) (k :: PType) (v :: PType) (s :: S).
(PIsData k, PIsData v, forall (s' :: S). Monoid (Term s' m)) =>
Term s ((k :--> (v :--> m)) :--> (PMap 'Sorted k v :--> m))
pfoldMapWithKey = forall (a :: PType) (s :: S).
HasCallStack =>
ClosedTerm a -> Term s a
phoistAcyclic forall a b. (a -> b) -> a -> b
$
  forall a (b :: PType) (s :: S) (c :: PType).
(PLamN a b s, HasCallStack) =>
(Term s c -> a) -> Term s (c :--> b)
plam forall a b. (a -> b) -> a -> b
$ \Term s (k :--> (v :--> m))
f Term s (PMap 'Sorted k v)
kvs ->
    forall (a :: PType) (k :: PType) (v :: PType) (s :: S).
(PIsData k, PIsData v) =>
Term
  s
  ((a :--> (k :--> (v :--> a)))
   :--> (a :--> (PMap 'Sorted k v :--> a)))
pfoldlWithKey forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# forall a (b :: PType) (s :: S) (c :: PType).
(PLamN a b s, HasCallStack) =>
(Term s c -> a) -> Term s (c :--> b)
plam (\Term s m
acc Term s k
k Term s v
v -> Term s m
acc forall a. Semigroup a => a -> a -> a
<> (Term s (k :--> (v :--> m))
f forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# Term s k
k forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# Term s v
v)) forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# forall a. Monoid a => a
mempty forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# Term s (PMap 'Sorted k v)
kvs