bimap -package:diagrams-lib -package:base-prelude -package:linear-base
base Data.Bifunctor,
lens Control.Lens.Combinators Control.Lens.Review,
semigroupoids Data.Bifunctor.Apply,
protolude Protolude,
streaming Streaming,
relude Relude.Functor.Reexport,
rio RIO.Prelude,
universum Universum.Functor.Reexport,
basement Basement.Compat.Bifunctor,
foundation Foundation,
rebase Rebase.Prelude,
stack Stack.Prelude,
incipit-base Incipit.Base,
loc Data.Loc.Internal.Prelude,
hledger-web Hledger.Web.Import,
termonad Termonad.Prelude Map over both arguments at the same time.
bimap f g ≡ first f . second g
Examples
>>> bimap toUpper (+1) ('j', 3)
('J',4)
>>> bimap toUpper (+1) (Left 'j')
Left 'J'
>>> bimap toUpper (+1) (Right 3)
Right 4
Bidirectional mapping between two key types
A data structure representing a bidirectional mapping between two key
types. Each value in the bimap is associated with exactly one value of
the opposite type.
Transform a graph by applying given functions to the vertices of each
part. Complexity:
O((n + m) * log(n)) time.
bimap f g empty == empty
bimap f g . vertex == vertex . Data.Bifunctor.bimap f g
bimap f g (edge x y) == edge (f x) (g y)
bimap id id == id
bimap f1 g1 . bimap f2 g2 == bimap (f1 . f2) (g1 . g2)
Map over both sides of a symbolic
Either at the same time
>>> let f = uninterpret "f" :: SInteger -> SInteger
>>> let g = uninterpret "g" :: SInteger -> SInteger
>>> prove $ \x -> fromLeft (bimap f g (sLeft x)) .== f x
Q.E.D.
>>> prove $ \x -> fromRight (bimap f g (sRight x)) .== g x
Q.E.D.
An implementation of bidirectional maps between values of two key
types. A
Bimap is essentially a bijection between subsets of
its two argument types.
Each element of the left-hand type is associated with an element of
the right-hand type, and vice-versa, such that the two mappings are
inverses. Deleting an element will cause its twin to be deleted, and
inserting a pair of elements will cause any overlapping bindings to be
deleted.
Most functions implicitly consider the left-hand type to be the key,
and the right-hand type to be the value. Functions with an
R
suffix reverse this convention, treating the right-hand type as the
key and the left-hand type as the value.
A bidirectional map between values of types a and b.
Bidirectional map. Essentially, a bijection between subsets of its two
argument types.
For one value of the left-hand type this map contains one value of the
right-hand type and vice versa.
Type-level
bimap.
>>> :kind! Eval (Bimap ((+) 1) (Flip (-) 1) '(2, 4))
Eval (Bimap ((+) 1) (Flip (-) 1) '(2, 4)) :: (Nat, Nat)
= '(3, 3)
Partly invertible finite maps.
Time complexities are given under the assumption that all relevant
instance functions, as well as arguments of function type, take
constant time, and "n" is the number of keys involved in the
operation.
Finite maps from
k to
v, with a way to quickly get
from
v to
k for certain values of type
v
(those for which
tag is defined).
Every value of this type must satisfy
biMapInvariant.
Bijection between finite sets.
Both data types are strict here.
The
bimapAccumL function behaves like a combination of
bimap and
bifoldl; it traverses a structure from left to
right, threading a state of type
a and using the given
actions to compute new elements for the structure.
Examples
Basic usage:
>>> bimapAccumL (\acc bool -> (acc + 1, show bool)) (\acc string -> (acc * 2, reverse string)) 3 (True, "foo")
(8,("True","oof"))
The
bimapAccumR function behaves like a combination of
bimap and
bifoldr; it traverses a structure from right
to left, threading a state of type
a and using the given
actions to compute new elements for the structure.
Examples
Basic usage:
>>> bimapAccumR (\acc bool -> (acc + 1, show bool)) (\acc string -> (acc * 2, reverse string)) 3 (True, "foo")
(7,("True","oof"))