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

com.github.mperry.fg.WriterM.groovy Maven / Gradle / Ivy

There is a newer version: 0.8
Show newest version
package com.github.mperry.fg

import fj.F
import fj.F2
import groovy.transform.TypeChecked

/**
 * Created by MarkPerry on 11/01/14.
 *
 * The a is the value in the monad and w is the log value (a monoid)
 */
@TypeChecked
class WriterM {

    A value
    W log
    F2 plus

    WriterM(A a, W w, F2 f) {
        value = a
        log = w
        plus = f
    }

    static WriterM lift(A a, W w, F2 f) {
        new WriterM(a, w, f)
    }

    def WriterM tell(W w) {
        WriterM.lift(value, plus.f(log, w), plus)
    }

    def  WriterM map(F f) {
        WriterM.lift(f.f(value), log, plus)
    }

    def  WriterM map(Closure c) {
        map(c as F)
    }

    def WriterM flatMap(F> f) {
        def writer = f.f(value)
        WriterM.lift(writer.value, plus.f(log, writer.log), plus)
    }

    def WriterM flatMap(Closure c) {
        flatMap(c as F)
    }

    static WriterM lift(A a) {
        WriterM.lift(a, STRING_EMPTY, STRING_CONCAT)
    }

    static WriterM log(A a) {
        WriterM.lift(a, LOG_FUNCTION.f(a), STRING_CONCAT)
    }

    static F> log() {
        { A a -> WriterM.lift(a, LOG_FUNCTION.f(a), STRING_CONCAT) } as F
    }

    static F LOG_FUNCTION = { Object o -> "Added $o to the log\n"} as F
    static F2 STRING_CONCAT = {String a, String b -> a + b} as F2
    static String STRING_EMPTY = ""

}