Skip to content

Commit f00a356

Browse files
committed
Correct the unionWith fusion wording
The fusion is a constant-factor change, not the elimination of the These intermediate it was described as. Map.union still produces a per-key These and the inner These is still built transiently for shared keys; what the fusion removes is one of the two outer Map.map passes over the post-union map, plus the wrap-then-remap of single-side currencies. Adjust the changelog and drop Note [Single-pass unionWith] accordingly; the merge structure is plain from the code. For IntersectMBO/plutus-private#2243.
1 parent dac80e8 commit f00a356

2 files changed

Lines changed: 3 additions & 11 deletions

File tree

plutus-ledger-api/changelog.d/20260527_131134_yuriy.lazaryev_issue_2243_fused_unionwith.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
### Changed
22

3-
- Fused `unionWith` in `PlutusLedgerApi.V1.Data.Value` into two outer passes (`Map.union` + a single `Map.map`), down from the previous three. The new implementation no longer materialises the intermediate `Map TokenName (These Integer Integer)` stage that the discarded `unionVal` helper used to produce; `These` wrapping survives only at the outer `CurrencySymbol` level, where it is collapsed in place.
3+
- Fused `unionWith` in `PlutusLedgerApi.V1.Data.Value` into two outer passes (`Map.union` + a single `Map.map`), down from the previous three. The discarded `unionVal` helper returned a full `Map CurrencySymbol (Map TokenName (These Integer Integer))` that `unionWith` then re-traversed; folding it in removes that second outer walk, and a currency present on only one side now has its token map mapped once rather than wrapped and then re-mapped. The `Map.union` lookup-and-merge core is unchanged, so this is a constant-factor improvement, not an algorithmic one.
44

55
- Fused `checkBinRel` along the same shape, walking the outer `Map.union` result with `Map.all` and applying the relation directly against `0` on whichever side is missing. The walk short-circuits on the first failing pair, giving `geq` / `leq` / `gt` / `lt` early exit on inputs that violate the relation near the start of their key set.
66

plutus-ledger-api/src/PlutusLedgerApi/V1/Data/Value.hs

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -402,13 +402,6 @@ assetClassValueOf :: Value -> AssetClass -> Integer
402402
assetClassValueOf v (AssetClass (c, t)) = valueOf v c t
403403
{-# INLINEABLE assetClassValueOf #-}
404404

405-
{- Note [Single-pass unionWith]
406-
'Map.union' tags each currency symbol with a 'These' recording which side(s)
407-
hold it. 'fuseInners' consumes that tag in one outer 'Map.map': against an
408-
implicit @0@ on the absent side, or — when both sides hold the symbol — over
409-
the inner @Map.union innerL innerR@. The merge therefore touches each level
410-
once and never materialises a @Map TokenName (These Integer Integer)@. -}
411-
412405
{-| Combine two 'Value' maps with the argument function.
413406
Assumes the well-definedness of the two maps. -}
414407
unionWith :: (Integer -> Integer -> Integer) -> Value -> Value -> Value
@@ -454,9 +447,8 @@ isZero (Value xs) = Map.all (Map.all (\i -> 0 == i)) xs
454447
{-| Check whether a binary relation holds for value pairs of two 'Value' maps,
455448
supplying 0 where a key is only present in one of them.
456449
457-
Shares the structure of 'unionWith' (see Note [Single-pass unionWith]), with
458-
'Map.all' in place of 'Map.map': the walk short-circuits on the first pair
459-
that fails @f@, applying the relation against @0@ on whichever side is absent. -}
450+
Walks the outer 'Map.union' with 'Map.all', short-circuiting on the first pair
451+
that fails @f@. -}
460452
checkBinRel :: (Integer -> Integer -> Bool) -> Value -> Value -> Bool
461453
checkBinRel f (Value mapL) (Value mapR) =
462454
Map.all checkInners (Map.union mapL mapR)

0 commit comments

Comments
 (0)