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

com.github.tonivade.purefun.monad.Writer 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.monad;

import static com.github.tonivade.purefun.Function1.cons;
import static com.github.tonivade.purefun.Function1.identity;

import com.github.tonivade.purefun.Function1;
import com.github.tonivade.purefun.HigherKind;
import com.github.tonivade.purefun.Tuple;
import com.github.tonivade.purefun.Tuple2;
import com.github.tonivade.purefun.typeclasses.Monoid;

@HigherKind
public interface Writer {

  Monoid monoid();
  Tuple2 value();

  default A getValue() {
    return value().get2();
  }

  default L getLog() {
    return value().get1();
  }

  default  Writer map(Function1 mapper) {
    return bimap(monoid(), identity(), mapper);
  }

  default  Writer mapLog(Monoid monoidR, Function1 mapper) {
    return bimap(monoidR, mapper, identity());
  }

  default Writer append(L log2) {
    return mapLog(monoid(), log1 -> monoid().combine(log1, log2));
  }

  default Writer reset() {
    return mapLog(monoid(), cons(monoid().zero()));
  }

  default  Writer bimap(Monoid monoidV, Function1 mapper1, Function1 mapper2) {
    return writer(monoidV, value().map(mapper1, mapper2));
  }

  default  Writer flatMap(Function1> mapper) {
    Writer apply = mapper.apply(value().get2());
    Tuple2 combine = value().map1(log -> monoid().combine(log, apply.getLog()));
    return writer(monoid(), Tuple.of(combine.get1(), apply.getValue()));
  }

  static  Writer pure(Monoid monoid, A value) {
    return writer(monoid, Tuple.of(monoid.zero(), value));
  }

  static  Writer writer(Monoid monoid, Tuple2 value) {
    return new Writer() {

      @Override
      public Monoid monoid() { return monoid; }

      @Override
      public Tuple2 value() { return value; }
    };
  }
}