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

com.github.tonivade.purefun.PartialFunction1 Maven / Gradle / Ivy

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

import com.github.tonivade.purefun.data.ImmutableArray;
import com.github.tonivade.purefun.data.ImmutableMap;
import com.github.tonivade.purefun.type.Option;

public interface PartialFunction1 {

  R apply(A value);

  boolean isDefinedAt(A value);

  default Function1> lift() {
    return value -> isDefinedAt(value) ? Option.some(apply(value)) : Option.none();
  }

  default  PartialFunction1 andThen(Function1 after) {
    return of(this::isDefinedAt, value -> after.apply(apply(value)));
  }

  default  Function1 compose(Function1 before) {
    return value -> apply(before.apply(value));
  }

  default PartialFunction1 orElse(PartialFunction1 other) {
    final PartialFunction1 self = PartialFunction1.this;
    return of(value -> self.isDefinedAt(value) || other.isDefinedAt(value),
              value -> self.isDefinedAt(value) ? self.apply(value) : other.apply(value));
  }

  default R applyOrElse(A value, Function1 orElse) {
    if (isDefinedAt(value)) {
      return apply(value);
    }
    return orElse.apply(value);
  }

  static  PartialFunction1 of(Matcher1 isDefined, Function1 apply) {
    return new PartialFunction1() {

      @Override
      public boolean isDefinedAt(A value) {
        return isDefined.match(value);
      }

      @Override
      public R apply(A value) {
        return apply.apply(value);
      }
    };
  }

  static  PartialFunction1 from(ImmutableArray array) {
    return of(position -> position >= 0 && position < array.size(), array::get);
  }

  static  PartialFunction1 from(ImmutableMap map) {
    return of(map::containsKey, key -> map.get(key).get());
  }
}