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

com.github.tonivade.purefun.optics.PPrism Maven / Gradle / Ivy

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

import static com.github.tonivade.purefun.Function1.cons;
import static com.github.tonivade.purefun.Function1.identity;
import static java.util.Objects.requireNonNull;

import com.github.tonivade.purefun.Function1;
import com.github.tonivade.purefun.type.Either;
import com.github.tonivade.purefun.type.Option;

public final class PPrism {

  private final Function1> getOrModify;
  private final Function1 reverseGet;

  protected PPrism(Function1> getOrModify, Function1 reverseGet) {
    this.getOrModify = requireNonNull(getOrModify);
    this.reverseGet = requireNonNull(reverseGet);
  }

  public static  PPrism of(Function1> getOrModify, Function1 reverseGet) {
    return new PPrism<>(getOrModify, reverseGet);
  }

  public Option getOption(S target) {
    return getOrModify.apply(target).toOption();
  }

  public T reverseGet(B value) {
    return reverseGet.apply(value);
  }

  public Either getOrModify(S target) {
    return getOrModify.apply(target);
  }

  public Function1 modify(Function1 mapper) {
    return target -> getOrModify(target).fold(identity(), a -> reverseGet(mapper.apply(a)));
  }

  public T modify(S target, Function1 mapper) {
    return modify(mapper).apply(target);
  }

  public Function1 set(B value) {
    return modify(cons(value));
  }

  public T set(S target, B value) {
    return set(value).apply(target);
  }

  public Function1> modifyOption(Function1 mapper) {
    return target -> getOption(target).map(mapper).map(reverseGet);
  }

  public Function1> setOption(B value) {
    return modifyOption(ignore -> value);
  }

  public POptional asOptional() {
    return POptional.of(this::set, this::getOrModify);
  }

  public  PPrism compose(PPrism other) {
    return new PPrism<>(
        target -> getOrModify(target).flatMap(a -> other.getOrModify(a).bimap(b -> set(target, b), identity())),
        value -> this.reverseGet(other.reverseGet(value)));
  }

  public  POptional compose(POptional other) {
    return asOptional().compose(other);
  }

  public  PPrism compose(PIso other) {
    return compose(other.asPrism());
  }

  public  POptional compose(PLens other) {
    return asOptional().compose(other);
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy