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

fj.data.optic.Optional Maven / Gradle / Ivy

Go to download

Functional Java is an open source library that supports closures for the Java programming language

There is a newer version: 5.0
Show newest version
package fj.data.optic;

import fj.F;
import fj.Function;
import fj.P;
import fj.P1;
import fj.P2;
import fj.control.Trampoline;
import fj.control.parallel.Promise;
import fj.control.parallel.Strategy;
import fj.data.Either;
import fj.data.IO;
import fj.data.IOFunctions;
import fj.data.List;
import fj.data.Option;
import fj.data.Stream;
import fj.data.Validation;
import fj.data.vector.V;
import fj.data.vector.V2;

/** {@link POptional} restricted to monomorphic update */
public final class Optional extends POptional {

  final POptional pOptional;

  public Optional(final POptional pOptional) {
    this.pOptional = pOptional;
  }

  @Override
  public F set(final A a) {
    return pOptional.set(a);
  }

  @Override
  public  F> modifyValidationF(final F> f) {
    return pOptional.modifyValidationF(f);
  }

  @Override
  public F> modifyV2F(final F> f) {
    return pOptional.modifyV2F(f);
  }

  @Override
  public F> modifyTrampolineF(final F> f) {
    return pOptional.modifyTrampolineF(f);
  }

  @Override
  public F> modifyStreamF(final F> f) {
    return pOptional.modifyStreamF(f);
  }

  @Override
  public F> modifyPromiseF(final F> f) {
    return pOptional.modifyPromiseF(f);
  }

  @Override
  public F> modifyP1F(final F> f) {
    return pOptional.modifyP1F(f);
  }

  @Override
  public F> modifyOptionF(final F> f) {
    return pOptional.modifyOptionF(f);
  }

  @Override
  public F> modifyListF(final F> f) {
    return pOptional.modifyListF(f);
  }

  @Override
  public F> modifyIOF(final F> f) {
    return pOptional.modifyIOF(f);
  }

  @Override
  public  F> modifyFunctionF(final F> f) {
    return pOptional.modifyFunctionF(f);
  }

  @Override
  public  F> modifyEitherF(final F> f) {
    return pOptional.modifyEitherF(f);
  }

  @Override
  public F modify(final F f) {
    return pOptional.modify(f);
  }

  @Override
  public Either getOrModify(final S s) {
    return pOptional.getOrModify(s);
  }

  @Override
  public Option getOption(final S s) {
    return pOptional.getOption(s);
  }

  /** join two {@link Optional} with the same target */
  public  Optional, A> sum(final Optional other) {
    return new Optional<>(pOptional.sum(other.pOptional));
  }

  @Override
  public  Optional, P2> first() {
    return new Optional<>(pOptional.first());
  }

  @Override
  public  Optional, P2> second() {
    return new Optional<>(pOptional.second());
  }

  /**************************************************************/
  /** Compose methods between a {@link Optional} and another Optics */
  /**************************************************************/

  /** compose a {@link Optional} with a {@link Setter} */
  public  Setter composeSetter(final Setter other) {
    return new Setter<>(pOptional.composeSetter(other.pSetter));
  }

  /** compose a {@link Optional} with a {@link Traversal} */
  public  Traversal composeTraversal(final Traversal other) {
    return new Traversal<>(pOptional.composeTraversal(other.pTraversal));
  }

  /** compose a {@link Optional} with a {@link Optional} */
  public  Optional composeOptional(final Optional other) {
    return new Optional<>(pOptional.composeOptional(other.pOptional));
  }

  /** compose a {@link Optional} with a {@link Prism} */
  public  Optional composePrism(final Prism other) {
    return new Optional<>(pOptional.composePrism(other.pPrism));
  }

  /** compose a {@link Optional} with a {@link Lens} */
  public  Optional composeLens(final Lens other) {
    return new Optional<>(pOptional.composeLens(other.pLens));
  }

  /** compose a {@link Optional} with an {@link Iso} */
  public  Optional composeIso(final Iso other) {
    return new Optional<>(pOptional.composeIso(other.pIso));
  }

  /********************************************************************/
  /** Transformation methods to view a {@link Optional} as another Optics */
  /********************************************************************/

  /** view a {@link Optional} as a {@link Setter} */
  @Override
  public Setter asSetter() {
    return new Setter<>(pOptional.asSetter());
  }

  /** view a {@link Optional} as a {@link Traversal} */
  @Override
  public Traversal asTraversal() {
    return new Traversal<>(pOptional.asTraversal());
  }

  public static  Optional id() {
    return new Optional<>(POptional.pId());
  }

  public static  Optional ignored() {
    return optional(s -> Option.none(), a -> s -> s);
  }

  public static final  Optional optional(final F> getOption, final F> set) {
    return new Optional<>(new POptional() {

      @Override
      public Either getOrModify(final S s) {
        return getOption.f(s).option(Either.left(s), Either.right_());
      }

      @Override
      public F set(final A a) {
        return set.f(a);
      }

      @Override
      public Option getOption(final S s) {
        return getOption.f(s);
      }

      @Override
      public  F> modifyFunctionF(final F> f) {
        return s -> getOption.f(s).> option(
            (C __) -> s,
            a -> Function.compose(b -> set.f(b).f(s), f.f(a))
            );
      }

      @Override
      public  F> modifyEitherF(final F> f) {
        return s -> getOption.f(s).> option(
            Either.right(s),
            t -> f.f(t).right().map(b -> set.f(b).f(s))
            );
      }

      @Override
      public F> modifyIOF(final F> f) {
        return s -> getOption.f(s).option(
            IOFunctions.unit(s),
            a -> IOFunctions.map(f.f(a), b -> set.f(b).f(s))
            );
      }

      @Override
      public F> modifyTrampolineF(final F> f) {
        return s -> getOption.f(s).option(
            Trampoline.pure(s),
            t -> f.f(t).map(b -> set.f(b).f(s))
            );
      }

      @Override
      public F> modifyPromiseF(final F> f) {
        return s -> getOption.f(s).> option(
            () -> Promise.promise(Strategy.idStrategy(), P.p(s)),
            t -> f.f(t).fmap(b -> set.f(b).f(s))
            );
      }

      @Override
      public F> modifyListF(final F> f) {
        return s -> getOption.f(s).> option(
            () -> List.single(s),
            t -> f.f(t).map(b -> set.f(b).f(s))
            );
      }

      @Override
      public F> modifyOptionF(final F> f) {
        return s -> getOption.f(s).option(
            Option.some(s),
            t -> f.f(t).map(b -> set.f(b).f(s))
            );
      }

      @Override
      public F> modifyStreamF(final F> f) {
        return s -> getOption.f(s).> option(
            () -> Stream.single(s),
            t -> f.f(t).map(b -> set.f(b).f(s))
            );
      }

      @Override
      public F> modifyP1F(final F> f) {
        return s -> getOption.f(s).> option(
            P.p(s),
            t -> f.f(t).map(b -> set.f(b).f(s))
            );
      }

      @Override
      public  F> modifyValidationF(final F> f) {
        return s -> getOption.f(s).> option(
            () -> Validation. success(s),
            t -> f.f(t).map(b -> set.f(b).f(s))
            );
      }

      @Override
      public F> modifyV2F(final F> f) {
        return s -> getOption.f(s).> option(
            () -> V.v(s, s),
            t -> f.f(t).map(b -> set.f(b).f(s))
            );
      }

      @Override
      public F modify(final F f) {
        return s -> getOption.f(s).option(s, a -> set.f(f.f(a)).f(s));
      }

    });
  }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy