Android-Monad

Additional

Language
Java
Version
0.1.0 (Nov 8, 2015)
Created
Oct 25, 2015
Updated
Dec 3, 2015 (Retired)
Owner
petitviolet
Contributor
petitviolet
1
Activity
Badge
Generate
Download
Source code

Android-Monad

This repository is Yet Another Android-M.

Implemented "Monadic" data structures.

Set up

dependencies {
    compile 'net.petitviolet.android:monad:latest-version'
}

And, I strongly recommend to use orfjackal/retrolambda together.

How to Use

Maybe

The name of Maybe is derived from Haskell. In Scala, Option.

// with lambda
Maybe<Integer> maybeInt = Maybe.of(x);
maybeInt.flatMap(integer -> Maybe.of(integer % 2 == 0 ? integer : null))
        .map(integer -> integer + 5)
        .filter(integer -> integer % 3 == 0)
        .foreach(integer -> Log.d(TAG, "result: " + integer));

// without lambda
maybeInt.flatMap(new Function.F1<Integer, Maybe<Integer>>() {
    @Override
    public Maybe<Integer> invoke(Integer integer) {
        return Maybe.of(integer % 2 == 0 ? integer : null);
    }
}).map(new Function.F1<Integer, Integer>() {
    @Override
    public Integer invoke(Integer integer) {
        return integer + 5;
    }
}).filter(new Function.F1<Integer, Boolean>() {
    @Override
    public Boolean invoke(Integer integer) {
        return integer % 3 == 0;
    }
}).foreach(new Function.F<Integer>() {
    @Override
    public void invoke(Integer integer) {
        Log.d(TAG, "result: " + integer);
    }
});

More detailes of Maybe interface is shown in MaybeTest.java.

ListM

Implemented ListM based on ArrayList as a implementation of List interface.

ListM<Integer> listM = ListM.unit();
listM.addAll(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10));
ListM<String> result = listM.filter(i -> i % 3 == 0)
        .flatMap(i -> ListM.<Integer>of(i * 10))
        .map(s -> s + "!");
        .foldRight((a, acc) -> a + ", " + acc, " <= end");
// result -> 90!, 60!, 30!, <= end

More detailes of ListM interface is shown in ListMTest.java.

State

State monad. Sequencial computations share a state, and each of them uses the state and modify or not, then pass it to next computation.

// state is List<String>, and value is Integer
Tuple<Integer, List<String>> result =
        State.init((List<String> strings) -> {
            // modify state
            strings.add("nice");
            // value is 1
            return Tuple.of(1, strings);
        }).map(i -> {
            // apply function to value of State
            return i + 10;
        }).map(i -> {
            // apply function to value of State
            return i * 2;
        }).flatMap(integer -> {
            // apply function to value of State
            return State.init(strings -> {
                if (integer % 2 == 0) {
                    // modify state
                    strings.add("awesome");
                    return Tuple.of(integer, strings);
                } else {
                    // modify state
                    strings.add("Oops");
                    return Tuple.of(-100, strings);
                }
            });
        // empty list is given as the first state of above sequencial computations
        }).apply(new ArrayList<>());
assert result._1 == 22;
assert result._2 == List("nice", "awesome");  // dummy code

Identity

Id monad. Have a value and do nothing. Just monadic.

Identity<String> id = Identity.id("hoge");
Identity<Integer> result = id.flatMap(new Function.F1<String, Identity<Integer>>() {
        @Override
        public Identity<Integer> invoke(String s) {
        return Identity.id(s.length());
    }
});
assert result.value.equals(4);

Lisence

This code is licensed under the Apache Software License 2.0.