Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

To get a minimal idea, you can think about a monad as of a parametrized class: M<T>. Its functioning follows "monad laws" that allow you to do certain things with it, and with the value(s) of T wrapped my it. In particular, you can always "map" the values:

  M<T1>::map(f: (T1 -> T2)): M<T2>
  List<int>([1, 2, 3]).map(x => toString(x)) == List<string>(["1", "2", "3"])
You can always flatten the nested structure:

  M<M<T>>::flatten(): M<T>  // [["a", "b"], ["c", "d"]] -> ["a", "b", "c", "d"]
This is usually expressed in a different form, more fundamental:

  M<T1>::flatMap(f: (T1 => M<T2>)): M<T2>
  List(["a b", "c d"]).flatMap(x => x.split()) == List(["a", "b", "c", "d"])
You can notice how that map() thing does looping over a sequence for you.

But Optional<T> is also a monad:

  let x: Optional<int> = Some(1);
  let y: Optional<int> = Nothing;
  x.map(n => n + 1).map(n => n * 2) == Some(4);
  y.map(n => n + 1).map(n => n * 2) == Nothing;
As you see, the same map() (and flatMap()) does the condition checking for you. and can be chained safely.

You can also notice how chaining of map-like operations does operation sequencing:

  fetch(url).then(content => content.json()).then(data => process(data))
Your language, like JS/TS, can add some syntax sugar over it, and allow you to write it as a sequence of statements:

  async () => {
    const response = await fetch(url);
    const data = await response.json();
    process(data);
  } 
Promises are not exactly monads though, a Promise<Promise<T>> immediately transforms into Promise<T>. But other monadic properties are still there.


> immediately transforms into

Minor quibble, "can only be resolved as". The runtime absolutely holds Promise<Promise<T>>'s.


Splitting hairs even further: the .then() returns a resolved value of the inner Promise, not the inner Promise itself, when the outer Promise resolves, so not "immediately" indeed. That's where the flattening occurs, AFAICT.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: