Skip to content

Instantly share code, notes, and snippets.

@guilhermesilveira
Created March 27, 2012 13:30
Show Gist options
  • Save guilhermesilveira/2215876 to your computer and use it in GitHub Desktop.
Save guilhermesilveira/2215876 to your computer and use it in GitHub Desktop.
monad lists, o basico do map
package br.com.caelum.example.monad;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
interface Monad<A> {
<B> Monad<B> map(Function<A, B> f);
}
interface Function<A, B> {
B apply(A x);
}
/**
* For a monad monad list, T = monad
*/
interface MonadList<T> extends Monad<T>, Iterable<T> {
<B> MonadList<B> map(Function<T, B> f);
}
public class Runner {
public static void main(String[] args) {
EagerList eager = new EagerList(Arrays.asList(1, 2, 3));
Monad result = eager.map(new MultiplyBy2());
result = result.map(new Evaluator());
System.out.println("Chamei flatmaps, mas evaluei :( eager");
System.out.println();
LazyList lazy = new LazyList(Arrays.asList(1, 2, 3));
MonadList lazyResult = lazy.map(new MultiplyBy2());
lazyResult = lazyResult.map(new Evaluator());
System.out.println("Ate aqui nao evaluei, uhu... lazy");
for (Object x : lazyResult) {
System.out.println(x);
}
}
}
/**
* Imprime que voce esta evaluando ela
*/
class Evaluator<T> implements Function<T, T> {
public T apply(T x) {
System.out.println("ESTOU EVALUANDO AGORA!");
return x;
}
}
class EagerList<T> implements MonadList<T> {
private final java.util.List<T> list;
public EagerList(java.util.List<T> list) {
this.list = list;
}
public <B> EagerList<B> map(Function<T, B> f) {
java.util.List<B> result = new ArrayList<B>();
for (T x : list) {
result.add(f.apply(x));
}
return new EagerList<B>(result);
}
public Iterator<T> iterator() {
return list.iterator();
}
public String toString() {
return "[EAGER: " + list + "]";
}
}
class Identity<X, T> implements Function<T, T> {
public T apply(T x) {
return x;
}
}
/**
* Basta que o Iterable seja lazy que a evaluation é lazy
*/
class LazyList<X, T> implements MonadList<T> {
private final Iterable<X> original;
private final Function<X, T> transformer;
public static <T> LazyList<T, T> create(Iterable<T> list) {
return new LazyList<T, T>(list, new Identity<T, T>());
}
// pode manter so o construtor ou so a fabrica (acima)
public LazyList(Iterable<X> list) {
this(list, new Function<X, T>() {
public T apply(X x) {
return (T) x; // sorry
}
});
}
private LazyList(Iterable<X> list, Function<X, T> transformer) {
this.original = list;
this.transformer = transformer;
}
public <B> LazyList<T, B> map(Function<T, B> f) {
return new LazyList<T, B>(this, f);
}
public String toString() {
return "[LAZY: " + original + "]";
}
public Iterator<T> iterator() {
final Iterator<X> iterator = original.iterator();
return new Iterator<T>() {
public boolean hasNext() {
return iterator.hasNext();
}
public T next() {
return transformer.apply(iterator.next());
}
public void remove() {
iterator.remove();
}
};
}
}
class MultiplyBy2 implements Function<Integer, Integer> {
public Integer apply(Integer x) {
return x * 2;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment