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

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

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

import fj.F
import fj.P
import fj.P2
import fj.Unit
import groovy.transform.Canonical
import groovy.transform.TypeChecked
import groovy.transform.TypeCheckingMode

/**
 * Created by MarkPerry on 9/01/14.
 */
@TypeChecked
@Canonical
class State {

    F> run

    P2 run(S s) {
        run.f(s)
    }

    @TypeChecked(TypeCheckingMode.SKIP)
    static  State lift(F> f) {
        new State(f)
    }

//    @TypeChecked(TypeCheckingMode.SKIP)
    static  State liftS(F f) {
        State.lift({ S1 s ->
            def s2 = f.f(s)
            P.p(s2, s2)
        } as F)
    }

    @TypeChecked(TypeCheckingMode.SKIP)
    static  State unit(A1 a) {
        lift({ S1 s -> P.p(s, a)} as F)
    }

    def  State map(F f) {
        State.lift({ S s ->
            def p2 = run(s)
            def b = f.f(p2._2())
            P.p(p2._1(), b)
        } as F)
    }

    static State modify(F f) {
        State.get().flatMap { S s ->
            State.lift({ S s2 ->
//                def s3 = f.f(s)
                P.p(f.f(s), Unit.unit())
            } as F)

        }
    }

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

    @TypeChecked(TypeCheckingMode.SKIP)
    def  State mapState(F, P2> f) {
        new State({ S s ->
            def p = run(s)
            f.f(p)
        } as F)
    }

    @TypeChecked(TypeCheckingMode.SKIP)
    static  State flatMap(State mb, F> f) {
        mb.flatMap(f)
    }


    def  State flatMap(F> f) {
        new State({ S s ->
            def p = run(s)
            def a = p._2()
            def s2 = p._1()
            def smb = f.f(a)
            smb.run(s2)
        } as F)
    }

    def  State flatMap(Closure> c) {
        flatMap(c as F)
    }

    def  State unit(F> f) {
        lift(f)
    }

    @TypeChecked(TypeCheckingMode.SKIP)
    static  State get() {
        def f = { S1 s -> P.p(s, s) }
        State.lift(f as F)
    }

    State gets() {
        State.lift({ S s ->
            def p = run(s)
            def s2 = p._1()
            P.p(s2, s2)
        } as F)
    }

    @TypeChecked(TypeCheckingMode.SKIP)
    static  State put(S1 s) {
        State.lift({ Object z -> P.p(s, Unit.unit())} as F)
    }

    A eval(S s) {
        run(s)._2()
    }

    S exec(S s) {
        run(s)._1()
    }

    @TypeChecked(TypeCheckingMode.SKIP)
    State withs(F f) {
        lift(f.andThen(run))
    }

    static State gets(F f) {
        State.get().map({ S s -> f.f(s)} as F)
    }

}