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(); }