cyclops icon indicating copy to clipboard operation
cyclops copied to clipboard

Prefer more specific types for flatMap

Open johnmcclean opened this issue 7 years ago • 1 comments

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)

johnmcclean avatar Nov 05 '18 11:11 johnmcclean

+1

kwonglau avatar Dec 17 '20 20:12 kwonglau