{-| The module provides an automatic way to construct a bidirectional transformation (rougly speaking, a getter/setter pair) from a uni-directional transformation (or, a getter function). The module provides a class 'PackM'. Once we write a transformation of type @ h :: (Traversable src, Traversable tgt) => forall a m.PackM c a m => src a -> m (tgt a) @ then applying 'fwd' to obtain a forward transformation (so-called \"get\" or \"getter\") @ fwd h :: src c -> tgt c @ and applying `bwd` to obtain a backward transformation (so-called \"put\" or \"setter\"). @ bwd h :: (MonadError e m, Error e) => src c -> tgt c -> m (src c) @ assuming that @c@ is some concrete type and @src@ and @tgt@ are some concrete containers ('Data.Traversable' instances) with @Eq c@ and @Eq (tgt ())@. The correctness of the obtained bidirectional transformation (GetPut and PutGet) is guaranted for free. That is, the following laws hold (assuming that we use @'Either' 'String'@ for the result of 'bwd'). prop> bwd h s (fwd h s) = Right s prop> bwd h s v = Right s' implies fwd h s' = v -} module Data.BffMono ( Pack(..), PackM(..), liftO1, liftO2, fwd, bwd ) where import Data.BffMono.Base