cyclops
cyclops copied to clipboard
Prefer more specific types for flatMap
When the type changes it breaks left identity
Future<Integer> bindAndUnit = Future.ofResult(10).flatMap(i->Future.ofResult(i+10)));
//Future[20]
Future<Integer> applyF = Lambda.λ(i->Future.ofResult(i+10)))
.apply(10);
//Future[20]
But changing the Function to return a Maybe or Option also works, but breaks the law
java i->Maybe.just(10)
Future<Integer> bindAndUnit = Future.ofResult(10).flatMap(i->Maybe.just(i+10)));
//Future[20]
Maybe<Integer> applyF = Lambda.λ(i->Maybe.just(i+10)))
.apply(10);
//Maybe[20]
Areas affected
- All sub-types of MonadicValue (Eval, Future, Maybe, Option)
- All sub-types of ImmutableList (DifferenceList, IntMap, LazySeq, LazySeq, LazyString, NonEmptyList, Seq, Vector)
- ImmutableSet, ImmutableSortedSet, ImmutableQueue
- ReactiveSeq (e.g. FutureStream, ReactiveSeq)
Proposed Approach
This is a breaking change, and is a potential enhancement for cyclops 11 or 12.
- Use concatMap to flatMap to an Iterable type
- Use mergeMap to flatMap to a reactive-streams Publisher
- For ReactiveSeq flatMap is already defined via the Stream interface (so can't be changed without not implementing Stream)
- Remove flatMap from MonadicValue and implement type specific flatMap per affected type (Future, Eval, Option)
- Maybe's flatMap will still be affected as the return type from the inherited flatMap on Option will still be Option
- Remove flatMap from ImmutableList, ImmutableSet, ImmutableSortedSet and ImmutableQueue (provide type specific implementations on sub-classes)
+1