Welcome! Got a question? Do you have -Ypartial-unification turned on? Other FAQs: http://typelevel.org/cats/faq.html
Option[A]
is a program. There are two ways of constructing primitive programs in the " Optional
language". One is with pure[A](a: A): Option[A]
, the other is with empty[A]: Option[A]
. Then you have ways of composing these Optional programs. map
transforms the result of an Option[A]
into an Option[B]
, assuming you can encode this transformation as A => B
. But there is an interaction with empty
! empty.map(f) = empty
. This gives us semantics: optional programs can express short-circuiting. You can have more powerful ways of composing optional programs, for example by building programs that depend on the result of the previous program: Option[A] => (A => Option[B]) => Option[B]
, which is flatMap. Flatmap also shorcircuits on empty programs. Another way you can compose optional programs is by choice, by taking a different path when you find an empty
program, this is orElse
. Finally, when you are done composing, you need to run this program, which is A => Option[A] => A
, i.e. getOrElse
.
This exemplifies completely algebraic thinking: I could implement optional programs with the ADT you know as Option[A]
, or with Either[Unit, A]
, or with a function (Option.fold), but the way you write and reason about these, in the mindset I just laid out, is unchanged.
@vinayakpathak
or with a function (Option.fold)
what do you mean by this?
Option.fold
Option
is Option.fold
the point is that for things like Option, the implementation is easy enough that operational thinking can be helpful. But this doesn't scale to more complicated abstractions like the real cats.effect.IO or fs2.Stream
so algebraic thinking is where we think of things like IO
as programs and how we can compose them I guess? so in that sense algebraic thinking for IO
is pretty much the same as algebraic thinking for Option
?