package bjc.funcdata.theory; import java.util.function.Function; /** * A functor over a pair of heterogeneous types. * * @author ben * * @param * The type stored on the 'left' of the pair. * * @param * The type stored on the 'right' of the pair. */ public interface Bifunctor { /** * Alias for functor mapping. * * @author EVE * * @param * The old left type. * * @param * The old right type. * * @param * The new left type. * * @param * The new right type. */ public interface BifunctorMap extends Function, Bifunctor> { /* * Alias */ } /** * Alias for left functor mapping. * * @author EVE * * @param * The old left type. * * @param * The old right type. * * @param * The new left type. */ public interface LeftBifunctorMap extends BifunctorMap { /* * Alias */ } /** * Alias for right functor mapping. * * @author EVE * * @param * The old left type. * * @param * The old right type. * * @param * The new right type. */ public interface RightBifunctorMap extends BifunctorMap { /* * Alias */ } /** * Lift a pair of functions to a single function that maps over both * parts of a pair. * * @param * The old left type of the pair. * * @param * The old right type of the pair. * * @param * The new left type of the pair. * * @param * The new right type of the pair. * * @param leftFunc * The function that maps over the left of the pair. * * @param rightFunc * The function that maps over the right of the pair. * * @return A function that maps over both parts of the pair. */ public default BifunctorMap bimap( final Function leftFunc, final Function rightFunc) { final BifunctorMap bimappedFunc = (argPair) -> { final LeftBifunctorMap leftMapper = argPair.fmapLeft(leftFunc); final Bifunctor leftMappedFunctor = leftMapper.apply(argPair); final RightBifunctorMap rightMapper = leftMappedFunctor .fmapRight(rightFunc); return rightMapper.apply(leftMappedFunctor); }; return bimappedFunc; } /** * Lift a function to operate over the left part of this pair. * * @param * The old left type of the pair. * * @param * The old right type of the pair. * * @param * The new left type of the pair. * * @param func * The function to lift to work over the left side of the pair. * * @return The function lifted to work over the left side of bifunctors. */ public LeftBifunctorMap fmapLeft( Function func); /** * Lift a function to operate over the right part of this pair. * * @param * The old left type of the pair. * * @param * The old right type of the pair. * * @param * The new right type of the pair. * * @param func * The function to lift to work over the right side of the pair. * * @return The function lifted to work over the right side of * bifunctors. */ public RightBifunctorMap fmapRight( Function func); /** * Get the value contained on the left of this bifunctor. * * @return The value on the left side of this bifunctor. */ public LeftType getLeft(); /** * Get the value contained on the right of this bifunctor. * * @return The value on the right of this bifunctor. */ public RightType getRight(); }