/* * esodata - data structures and other things, of varying utility * Copyright 2022, Ben Culkin * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ 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(); }