All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.tonivade.purefun.instances.ConstInstances Maven / Gradle / Ivy

/*
 * Copyright (c) 2018-2022, Antonio Gabriel Muñoz Conejo 
 * Distributed under the terms of the MIT License
 */
package com.github.tonivade.purefun.instances;

import com.github.tonivade.purefun.Eq;
import com.github.tonivade.purefun.Function1;
import com.github.tonivade.purefun.Function2;
import com.github.tonivade.purefun.Kind;
import com.github.tonivade.purefun.Witness;
import com.github.tonivade.purefun.type.Const;
import com.github.tonivade.purefun.type.ConstOf;
import com.github.tonivade.purefun.type.Const_;
import com.github.tonivade.purefun.type.Eval;
import com.github.tonivade.purefun.type.EvalOf;
import com.github.tonivade.purefun.typeclasses.Applicative;
import com.github.tonivade.purefun.typeclasses.Contravariant;
import com.github.tonivade.purefun.typeclasses.Foldable;
import com.github.tonivade.purefun.typeclasses.Functor;
import com.github.tonivade.purefun.typeclasses.Monoid;
import com.github.tonivade.purefun.typeclasses.Traverse;

  @SuppressWarnings("unchecked")
public interface ConstInstances {

  static  Eq, A>> eq(Eq eq) {
    return (a, b) -> eq.eqv(a.fix(ConstOf::narrowK).get(), a.fix(ConstOf::narrowK).get());
  }

  static  Functor> functor() {
    return ConstFunctor.INSTANCE;
  }

  static  Applicative> applicative(Monoid monoid) {
    return ConstApplicative.instance(monoid);
  }

  static  Foldable> foldable() {
    return ConstFoldable.INSTANCE;
  }

  static  Traverse> traverse() {
    return ConstTraverse.INSTANCE;
  }

  static  Contravariant> contravariant() {
    return ConstContravariant.INSTANCE;
  }
}

interface ConstFunctor extends Functor> {

  @SuppressWarnings("rawtypes")
  ConstFunctor INSTANCE = new ConstFunctor() {};

  @Override
  default  Kind, B> map(Kind, ? extends A> value, Function1 map) {
    return value.fix(ConstOf::narrowK).retag();
  }
}

interface ConstApplicative extends Applicative> {

  static  ConstApplicative instance(Monoid monoid) {
    return () -> monoid;
  }

  Monoid monoid();

  @Override
  default  Const pure(A value) {
    return Const.of(monoid().zero());
  }

  @Override
  default  Const ap(
      Kind, ? extends A> value, 
      Kind, ? extends Function1> apply) {
    return Const.of(monoid().combine(
            apply.fix(ConstOf::narrowK).retag().get(),
            value.fix(ConstOf::narrowK).retag().get()));
  }
}

interface ConstContravariant extends Contravariant> {

  @SuppressWarnings("rawtypes")
  ConstContravariant INSTANCE = new ConstContravariant() {};

  @Override
  default  Const contramap(Kind, ? extends A> value, Function1 map) {
    return value.fix(ConstOf::narrowK).retag();
  }
}

interface ConstFoldable extends Foldable> {

  @SuppressWarnings("rawtypes")
  ConstFoldable INSTANCE = new ConstFoldable() {};

  @Override
  default  B foldLeft(Kind, ? extends A> value, B initial, 
      Function2 mapper) {
    return initial;
  }

  @Override
  default  Eval foldRight(
      Kind, ? extends A> value, Eval initial, 
      Function2, ? extends Eval> mapper) {
    return EvalOf.narrowK(initial);
  }
}

interface ConstTraverse extends Traverse>, ConstFoldable {

  @SuppressWarnings("rawtypes")
  ConstTraverse INSTANCE = new ConstTraverse() {};

  @Override
  default  Kind, B>> traverse(
      Applicative applicative, Kind, A> value, Function1> mapper) {
    return applicative.pure(value.fix(ConstOf::narrowK).retag());
  }
}