sitepodmatt
03/06/2019, 4:09 PMDerek Berner
03/06/2019, 4:20 PM(A) -> (B) -> C
. Passing that to Either<X, A>#map
would return a value of type Either<X, (B) -> C>
. If you want to get an Either<X, C>
out of it, you can it into Either<X, B>#ap
. This is arbitrarily chainable too.
Example: fun makePerson(name: String): (Int) => Person = { age: Int -> Person(name,age) }
val name: Either<X,String> = /*...*/
val age: Either<X,Int> = /*...*/
val person: Either<X,Person> = age.ap(name.map(::makePerson))
Applicative#map
makes this syntax much cleaner, and is implemented using ap
.sitepodmatt
03/06/2019, 4:23 PMDerek Berner
03/06/2019, 4:35 PMap
gets a lot of use in something like Haskell (where map
and ap
are called <$>
and <*>
, respectively) because you can use that syntax to go Person <$> name <*> age
(equivalent to Applicative#ap(Functor#map)
in Arrow), which, once you understand the operators, is a little nicer than liftA2 Person $ name age
(equivalent to Applicative#map
in Kotlin).sitepodmatt
03/07/2019, 2:42 AMsitepodmatt
03/07/2019, 2:42 AMval output = fn1.map({ it(2) })
val output2 = Some(2).ap(fn1)
val output3 = Some(2).flatMap({ v -> fn1.map({ it(v) }) })
println(output)
println(output2)
println(output3)
sitepodmatt
03/07/2019, 2:42 AMDerek Berner
03/07/2019, 3:58 PMDerek Berner
03/07/2019, 4:00 PMap
for monads uses flatMap