flatMap
takes f
that returns Sum
f: B => Sum[A, C] and construct it from trait Function1[-I, +O]{ def apply(i: I): O} it seems B is the contravariant argument while Sum[A, C] is the covariant term in this function
Right, but now if you write flatMap
you f
is in turn in negative position, so all the variances switch
This (section of this) article explains it well but it's in Haskell
Positive position: the type variable is the result/output/range/codomain of the function
Negative position: the type variable is the argument/input/domain of the function
When a type variable appears in positive position, the data type is covariant with that variable.
When the variable appears in negative position, the data type is contravariant with that variable.
flatMap
out, it should all fit
f
, Sum
is in positive position (return type)flatMap
is a function that takes f
, so all of f
is in negative position, which makes B
have positive position and Sum
have negative position
1
and -1
, they keep switching. Roughly speaking, functions of functions is the multiplication
List(1).withFilter(_ > 0)
val res63: scala.collection.WithFilter[Int,[_]List[_]] = scala.collection.IterableOps$WithFilter@cf76c0b
def something(list: List[_])
, then the [_]
is a wildcard, meaning you can pass a list value whose elements are any type.
[_]
there means "i don't care what the type is, so i'm going to forget its name", just like _
in places like pattern matching means "i don't care what this is, i'm not even going to name it")
if you use cats you can follow the examples at https://typelevel.org/cats/typeclasses/parallel.html#parallel
basically you write your validation functions to produce Either
. but you "glue together" those functions to act using Validated
, which then gets converted back to Either
at the end
mapN
from cats. it's like a mode: you switch from fail-fast (flatMap via Either) to collect-errors (mapN via Validated), and back.
val res63: scala.collection.WithFilter[Int, List] = ...
to be correct
mapN
also does it.
[A]Foo[Int, String, A]
- on this post about partial unification, so I guess it does have a specific meaning that I'm not familiar with