Skip to content

Commit

Permalink
Merge pull request #30 from aol/anyM-seqM-refactoring
Browse files Browse the repository at this point in the history
move monad into internal package, better unit tests / api
  • Loading branch information
johnmcclean committed Jul 1, 2015
2 parents 7022c0e + 30f91ea commit 44d58d1
Show file tree
Hide file tree
Showing 36 changed files with 509 additions and 859 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
import java.util.function.Function;
import java.util.function.Predicate;

import com.aol.cyclops.lambda.api.AsGenericMonad;
import com.aol.cyclops.internal.AsGenericMonad;
import com.aol.cyclops.internal.Monad;
import com.aol.cyclops.lambda.api.Comprehender;
import com.aol.cyclops.lambda.monads.Monad;

public class MonadMonadComprehender implements Comprehender<Monad> {

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.aol.cyclops.lambda.api;
package com.aol.cyclops.internal;

import java.util.Collection;
import java.util.Iterator;
Expand All @@ -7,7 +7,7 @@
import java.util.stream.Stream;

import com.aol.cyclops.comprehensions.converters.MonadicConverters;
import com.aol.cyclops.lambda.monads.Monad;
import com.aol.cyclops.lambda.api.Streamable;
import com.aol.cyclops.lambda.monads.MonadWrapper;

public class AsGenericMonad {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package com.aol.cyclops.lambda.monads;
package com.aol.cyclops.internal;

import static com.aol.cyclops.internal.AsGenericMonad.asMonad;
import static com.aol.cyclops.internal.AsGenericMonad.monad;


import static com.aol.cyclops.lambda.api.AsGenericMonad.asMonad;
import static com.aol.cyclops.lambda.api.AsGenericMonad.monad;



Expand All @@ -25,10 +27,15 @@
import java.util.stream.Stream;

import com.aol.cyclops.lambda.api.AsAnyM;
import com.aol.cyclops.lambda.api.AsGenericMonad;
import com.aol.cyclops.lambda.api.AsStreamable;
import com.aol.cyclops.lambda.api.Monoid;
import com.aol.cyclops.lambda.api.Streamable;
import com.aol.cyclops.lambda.monads.AnyM;
import com.aol.cyclops.lambda.monads.ComprehenderSelector;
import com.aol.cyclops.lambda.monads.Filterable;
import com.aol.cyclops.lambda.monads.Functor;
import com.aol.cyclops.lambda.monads.SequenceM;
import com.aol.cyclops.lambda.monads.StreamBasedFunctions;
import com.aol.cyclops.streams.StreamUtils;
import com.aol.cyclops.streams.Pair;
import com.nurkiewicz.lazyseq.LazySeq;
Expand Down Expand Up @@ -255,13 +262,8 @@ default MONAD unwrap(){
* }</pre>
*
*/
default <X> AnyM<X> anyM(){
return new AnyM<X>((Monad)this);
}
default <X> TraversableM<X> sequence(){
return new TraversableM<X>((Monad)this);
}

public <X> AnyM<X> anyM();
public <X> SequenceM<X> sequence();
/**
* Create a duck typed Monad wrapper. Using AnyM we focus only on the underlying type
* e.g. instead of
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,18 @@
package com.aol.cyclops.lambda.monads;
package com.aol.cyclops.internal;


import static com.aol.cyclops.lambda.api.AsGenericMonad.asMonad;
import static com.aol.cyclops.lambda.api.AsGenericMonad.monad;

import static com.aol.cyclops.internal.AsGenericMonad.asMonad;
import static com.aol.cyclops.internal.AsGenericMonad.monad;

import java.util.List;

import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Stream;

import com.aol.cyclops.lambda.api.AsGenericMonad;
import com.aol.cyclops.lambda.api.AsAnyM;

import com.aol.cyclops.lambda.api.Monoid;
import com.aol.cyclops.lambda.monads.ComprehenderSelector;
import com.aol.cyclops.streams.Pair;

public interface MonadFunctions<MONAD,T>{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@
import java.util.stream.Stream;

import com.aol.cyclops.comprehensions.converters.MonadicConverters;
import com.aol.cyclops.lambda.monads.MonadWrapper;
import com.aol.cyclops.lambda.monads.AnyM;
import com.aol.cyclops.lambda.monads.MonadWrapper;


public class AsAnyM extends AsGenericMonad{
public class AsAnyM {

/**
* Create a duck typed Monad wrapper. Using AnyM we focus only on the underlying type
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@
import java.util.stream.Stream;

import com.aol.cyclops.comprehensions.converters.MonadicConverters;
import com.aol.cyclops.lambda.monads.MonadWrapper;
import com.aol.cyclops.lambda.monads.AnyM;
import com.aol.cyclops.lambda.monads.MonadWrapper;


public class AsAnyMList extends AsGenericMonad{
public class AsAnyMList extends AsAnyM{


public static <T> List<AnyM<T>> notTypeSafeAnyMList(Collection<Object> anyM){
Expand Down
45 changes: 30 additions & 15 deletions cyclops-base/src/main/java/com/aol/cyclops/lambda/monads/AnyM.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.aol.cyclops.lambda.monads;

import static com.aol.cyclops.lambda.api.AsGenericMonad.asMonad;
import static com.aol.cyclops.lambda.api.AsGenericMonad.monad;
import static com.aol.cyclops.internal.AsGenericMonad.asMonad;
import static com.aol.cyclops.internal.AsGenericMonad.monad;

import java.util.Comparator;
import java.util.Iterator;
Expand All @@ -19,6 +19,8 @@
import lombok.AccessLevel;
import lombok.AllArgsConstructor;

import com.aol.cyclops.internal.AsGenericMonad;
import com.aol.cyclops.internal.Monad;
import com.aol.cyclops.lambda.api.AsAnyM;
import com.aol.cyclops.lambda.api.AsStreamable;
import com.aol.cyclops.lambda.api.Monoid;
Expand All @@ -28,7 +30,16 @@
import com.aol.cyclops.streams.StreamUtils;
import com.nurkiewicz.lazyseq.LazySeq;

@AllArgsConstructor(access=AccessLevel.PACKAGE)
/**
*
* Wrapper for Any Monad type
* @see AnyMonads companion class for static helper methods
*
* @author johnmcclean
*
* @param <T>
*/
@AllArgsConstructor(access=AccessLevel.PROTECTED)
public class AnyM<T> implements Unwrapable{

private final Monad<Object,T> monad;
Expand Down Expand Up @@ -104,9 +115,13 @@ public final <T1> AnyM<T1> flatten(){
* @param next Monad to aggregate content with
* @return Aggregated Monad
*/
public final <R> AnyM<R> aggregate(AnyM<?> next){
public final AnyM<T> aggregate(AnyM<T> next){
return monad.aggregate(next.monad).anyM();
}
public final <R> AnyM<List<R>> aggregateUntyped(AnyM<?> next){
return monad.aggregate(next.monad).anyM();
}


/**
* flatMap operation
Expand Down Expand Up @@ -138,7 +153,7 @@ public final <R> AnyM<R> flatMap(Function<? super T,AnyM<? extends R>> fn) {
*
* @return A Monad that wraps a Stream
*/
public final <NT> TraversableM<NT> traversable(Function<T,Stream<NT>> fn){
public final <NT> SequenceM<NT> toSequence(Function<T,Stream<NT>> fn){
return monad.flatMapToStream((Function)fn)
.sequence();
}
Expand All @@ -162,7 +177,7 @@ public final <NT> TraversableM<NT> traversable(Function<T,Stream<NT>> fn){
* @return A Monad that wraps a Stream
*/
public final <T> TraversableM<T> traversable(){
public final <T> SequenceM<T> toSequence(){
return monad.streamedMonad().sequence();
}

Expand All @@ -172,7 +187,7 @@ public final <T> TraversableM<T> traversable(){
* If the underlying monad is a Stream it is returned
* Otherwise we flatMap the underlying monad to a Stream type
*/
public final TraversableM<T> toTraversable(){
public final SequenceM<T> asSequence(){
return monad.sequence();

}
Expand Down Expand Up @@ -217,10 +232,10 @@ public final TraversableM<T> toTraversable(){
*
* @param o to wrap
* @return Duck typed Monad
*/
public static <T> AnyM<T> of(Object o){
return AsAnyM.notTypeSafeAnyM(o);
}
}*/



Expand Down Expand Up @@ -266,8 +281,8 @@ public final <R> AnyM<R> applyM(AnyM<Function<? super T,? extends R>> fn){
* @param fn
* @return
*/
public final <NT,R> Monad<NT,R> simpleFilter(AnyM<Predicate<? super T>> fn){
return monad.simpleFilter(fn.monad);
public final <R> AnyM<R> simpleFilter(AnyM<Predicate<? super T>> fn){
return monad.simpleFilter(fn.monad).anyM();


// filterM((a: Int) => List(a > 2, a % 2 == 0), List(1, 2, 3), ListMonad),
Expand All @@ -289,9 +304,9 @@ public final <NT,R> Monad<NT,R> simpleFilter(AnyM<Predicate<? super T>> fn){
* @param times number of times to replicate
* @return Replicated Monad
*/
public final <NT,R> Monad<NT,R> replicateM(int times){
public final <R> AnyM<R> replicateM(int times){

return monad.replicateM(times);
return monad.replicateM(times).anyM();
}
/**
* Perform a reduction where NT is a (native) Monad type
Expand All @@ -306,11 +321,11 @@ public final <NT,R> Monad<NT,R> replicateM(int times){
* @param reducer
* @return
*/
public final <NT,R> Monad<NT,R> reduceM(Monoid<NT> reducer){
public final <R> AnyM<R> reduceM(Monoid<R> reducer){
// List(2, 8, 3, 1).foldLeftM(0) {binSmalls} -> Optional(14)
// convert to list Optionals

return monad.reduceM(reducer);
return monad.reduceM(reducer).anyM();
}


Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,53 @@
package com.aol.cyclops.lambda.monads;

import java.util.Collection;
import java.util.List;
import java.util.Optional;
import static com.aol.cyclops.internal.AsGenericMonad.asMonad;

import java.util.concurrent.CompletableFuture;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.stream.BaseStream;
import java.util.stream.Stream;
import java.util.Collection;
import java.util.List;
import java.util.Optional;

import com.aol.cyclops.lambda.api.AsAnyM;
import com.aol.cyclops.lambda.api.AsGenericMonad;

import org.jooq.lambda.Seq;

public class Monads extends AsAnyM{
import com.aol.cyclops.internal.AsGenericMonad;
import com.aol.cyclops.lambda.api.AsAnyMList;
import com.nurkiewicz.lazyseq.LazySeq;


public class AnyMonads extends AsAnyMList{
public static final <T,R> Function<? super T,AnyM<? extends R>> streamToAnyM(Function<? super T,? extends BaseStream<R,?>> fn){
return t -> AsGenericMonad.asMonad(fn.apply(t)).anyM();
}
public static final <T,R> Function<? super T,AnyM<? extends R>> futureToAnyM(Function<? super T,? extends CompletableFuture<R>> fn){
return t -> AsGenericMonad.asMonad(fn.apply(t)).anyM();
}
public static final <T,R> Function<? super T,AnyM<? extends R>> optionalToAnyM(Function<? super T,? extends Optional<R>> fn){
return t -> AsGenericMonad.asMonad(fn.apply(t)).anyM();
}
public static final <T,R> Function<? super T,AnyM<? extends R>> lazySeqToAnyM(Function<? super T,? extends LazySeq<R>> fn){
return t -> AsGenericMonad.asMonad(fn.apply(t)).anyM();
}
public static final <T,R> Function<? super T,AnyM<? extends R>> seqToAnyM(Function<? super T,? extends Seq<R>> fn){
return t -> AsGenericMonad.asMonad(fn.apply(t)).anyM();
}
public static final <T,R> Function<? super T,SequenceM<? extends R>> streamToSequenceM(Function<? super T,? extends BaseStream<R,?>> fn){
return t -> AsGenericMonad.asMonad(fn.apply(t)).sequence();
}
public static final <T,R> Function<? super T,SequenceM<? extends R>> futureToSequenceM(Function<? super T,? extends CompletableFuture<R>> fn){
return t -> AsGenericMonad.asMonad(fn.apply(t)).sequence();
}
public static final <T,R> Function<? super T,SequenceM<? extends R>> optionalToSequenceM(Function<? super T,? extends Optional<R>> fn){
return t -> AsGenericMonad.asMonad(fn.apply(t)).sequence();
}
public static final <T,R> Function<? super T,SequenceM<? extends R>> lazySeqToSequenceM(Function<? super T,? extends LazySeq<R>> fn){
return t -> AsGenericMonad.asMonad(fn.apply(t)).sequence();
}
public static final <T,R> Function<? super T,SequenceM<? extends R>> seqToSequenceM(Function<? super T,? extends Seq<R>> fn){
return t -> AsGenericMonad.asMonad(fn.apply(t)).sequence();
}
/**
* Lift a function so it accepts a Monad and returns a Monad (simplex view of a wrapped Monad)
* Simplex view simplifies type related challenges. The actual native type is not specified here.
Expand Down Expand Up @@ -74,13 +108,13 @@ public static <T,R> AnyM<List<R>> traverse(Collection<AnyM<T>> seq, Function<T,R
if(seq.size()==0)
return anyM(Optional.empty());
return asMonad(new ComprehenderSelector().selectComprehender(seq.iterator().next().unwrap().getClass()).of(1))
.flatMap(in-> monad(seq.stream().map(it->it.unwrap())).flatten().flatMap((Function)fn).unwrap()
.flatMap(in-> asMonad(seq.stream().map(it->it.unwrap())).flatten().flatMap((Function)fn).unwrap()
).anyM();
}
public static <T,R> AnyM<List<R>> traverse(Stream<AnyM<T>> seq, Function<T,R> fn){

return asMonad(Stream.of(1))
.flatMap(in-> monad(seq).flatten().flatMap((Function)fn).unwrap()
.flatMap(in-> asMonad(seq).flatten().flatMap((Function)fn).unwrap()
).anyM();
}

Expand All @@ -107,14 +141,15 @@ public static <T1> AnyM<Stream<T1>> sequence(Collection<AnyM<T1>> seq){
if(seq.size()==0)
return anyM(Optional.empty());
else
return AsGenericMonad.asMonad(new ComprehenderSelector().selectComprehender(seq.iterator().next().unwrap().getClass()).of(1))
.flatMap(in-> monad(seq.stream().map(it->it.unwrap())).flatten().unwrap()).anyM();
return asMonad(new ComprehenderSelector().selectComprehender(seq.iterator().next().unwrap().getClass()).of(1))
.flatMap(in-> AsGenericMonad.asMonad(seq.stream().map(it->it.unwrap())).flatten().unwrap()).anyM();
}
public static <T1> AnyM<Stream<T1>> sequence(Stream<AnyM<T1>> seq){
return AsGenericMonad.asMonad(Stream.of(1))
.flatMap(in-> monad(seq.map(it->it.unwrap()))
.flatMap(in-> AsGenericMonad.asMonad(seq.map(it->it.unwrap()))
.flatten().unwrap())
.anyM();
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import lombok.Value;
import lombok.experimental.Wither;

import com.aol.cyclops.internal.Monad;
import com.aol.cyclops.lambda.api.Decomposable;

@Value
Expand All @@ -16,6 +17,12 @@ public static <MONAD,T> Monad<MONAD,T> of(Object of) {
public MONAD unwrap(){
return (MONAD)monad;
}


@Override
public <X> AnyM<X> anyM(){
return new AnyM<X>((Monad)this);
}
@Override
public <X> SequenceM<X> sequence(){
return new SequenceM<X>((Monad)this);
}
}

0 comments on commit 44d58d1

Please sign in to comment.