Skip to content
HomeVideosBooksBlogs
AllTop postsTopics
Podcasts
HistoryListsWatch laterLiked videosFollowing

The videos, books, blogs and podcasts Hacker News keeps recommending, all in one place.

VideosBooksBlogsPodcastsAboutPrivacySettings

Data from Hacker News, HackerTube, HackerBooks, HackerBlogs and Open Library. Credits · Not affiliated with Y Combinator.

HomeVideosBooksBlogsPodcasts
Ctrl K
    P

    Philip Nilsson

    philipnilsson.github.io · Personal blog · on HN since 2013

    Philip Nilsson writes about functional programming, including monads, monoids, and semigroups, in his Badness10k blog.

    Visit blogHN submissions
    ProgrammingLanguages & Compilers
    What HN says

    Commenters praise "Escaping Hell with Monads" as short and clear, and one teacher says it is what makes monads click for Haskell students.

    Stats for nerds
    19HN people shared it
    15linked in comments
    460story points
    May 2026last shared
    2017people per year2026

    Top posts on HN

    1. 1
      Escaping Hell with Monads (2017)
      6 people · 263 points · first shared 2017 · 213 comments on HN
    2. 2
      Algebraic Patterns – Monoid Morphism
      1 person · 86 points · first shared 2016 · 30 comments on HN
    3. 3
      Algebraic patterns – Semigroup
      1 person · 82 points · first shared 2016 · 39 comments on HN
    4. 4
      A functional solution to Twitter's waterflow problem
      1 person · 7 points · first shared 2013 · 2 comments on HN
    5. 5
      Escaping Hell with Monads
      10 people · 5 points · first shared 2017 · Discussion on HN
    6. 6
      Algebraic Patterns – Monoid
      1 person · 4 points · first shared 2016 · Discussion on HN
    7. 7
      Algebraic Patterns – Semigroup
      1 person · 3 points · first shared 2016 · Discussion on HN
    8. 8
      Functional patterns – Identity element
      1 person · 3 points · first shared 2016 · Discussion on HN
    9. 9
      Functional Patterns – Monoid
      1 person · 3 points · first shared 2016 · 1 comments on HN
    10. 10
      Algebraic Patterns – Category
      1 person · 2 points · first shared 2016 · Discussion on HN

    What HN people wrote when they linked it

    • one-punchJan 2020

      The code is mostly pure Haskell (the do block, which most Haskellers are familiar with), with a few domain-specific elements (those led and delay “assignments” and the Stream type in this functional reactive programming framework arduino-copilot, whose meaning is specific to this Arduino application and most Haskellers have to guess).

      The short answer is that I could guess what it means.

      This `arduino-copilot` example really showcases one killer application of Haskell: writing eDSL (embedded domain-specific language) in Haskell.

      Haskell allows really high level abstraction: in particular, you can overload the operator which combines different statements in Haskell. In C/C++, the semicolon combines subsequent statements, Haskell even allows you to overload (give a new meaning to) the semicolon “operator” (think of overloading ; instead of overloading +). That is, in Haskell we can interpret differently how to combine subsequent statements in different contexts (such as null-checking, exception handling, async/await style concurrency, looping, or procedural state passing, etc., see the example below).

      However, when we “overload the semicolon operator”, we intuitively have some expectations:

      1. We expect to be able to turn a value into a standalone statement (to inject a value as a single statement with that value, e.g., to turn the value “97” into the statement “97;”, and this operation is called return)

      2. We expect to be able to use the result of a statement in the…

    • benreesmanAug 2022

      Ah no the migration I was referring to is `Applicative`: I just upgraded our "primary" Nix `devShell` to use `9.2.4` (`RecordDotSyntax` is finally here, may the thousand-year reign of the Glorious Glasgow Haskell Compiler commence! /s) and it's hitting me with deprecation notices about `return = ...` rather than `return = pure` and/or omitting and explicit `return`. Which makes sense, the rationale is at https://gitlab.haskell.org/ghc/ghc/-/wikis/proposal/monad-of-no-return.

      I remember when I was working on `Haxl` at FB in like, 2015 or 2016, it needed `ApplicativeDo` and that was like, quite the novelty in industrial Haskell (I think it was already a no-brainer to the research/OSS/etc. crowd). So mainstreaming `Applicative` into the effects hierarchy has been going on for 6 or 7 years that I know about, and I bet a lot longer than that (the paper introducing `Applicative` is from 2008: https://www.staff.city.ac.uk/~ross/papers/Applicative.html).

      There's an (admittedly oversimplified) sales deck for algebraic effects that I have found really effective at selling this stuff to open-minded non-FP hackers: https://philipnilsson.github.io/Badness10k/posts/2017-05-07-escaping-hell-with-monads.html.

      At the risk of inviting an old-fashioned HN brigade gang-tackle: I think it indirectly illustrates why Rust is going to end up going all-in and ditching the ?-notation. Please don't hurt me.

    • lmmNov 2017

      As a Scala programmer, Kotlin always feels like a language that frustratingly almost gets it, but is infuriatingly unwilling to listen to experience of what works in large codebases. Look at the examples on https://philipnilsson.github.io/Badness10k/escaping-hell-with-monads/ - I think Kotlin has literally every one of those ad hoc solutions built into the language, but stubbornly avoids making the generalisation. In small examples ad hoc solutions look great, but to succeed in large codebases a language needs a generality and consistency that Kotlin lacks.

      E.g. already there's no way to reuse logic between code paths that operate on Kotlin nullable types, Java Options (needed for compatibility with Java streams or more generally other JVM libraries), or rust-style Result types (for which there are several Kotlin libraries already, because it's a very useful concept and the language mostly has the facilities to support it), even though all three behave almost identically and you would often want to do the same thing in all three cases. But since the language won't let you represent what these types have in common, your only option is to copy/paste the code.

    • ParetoOptimalMar 2022

      > So really monads are essentially an abbreviated syntax? Chaining functions, where (some of) the arguments are hidden from the language syntax and inserted by the compiler?

      That's a part of it, for instance see:

      https://philipnilsson.github.io/Badness10k/posts/2017-05-07-escaping-hell-with-monads.html

      I recently wrote a note related to this that had a useful exchange:

      >> When you see a "do" block, where do you look to figure out what it's actually doing?

      > If you need to know, you look at what consumes the result. If it's abstract (say it's a top level binding `... -> m a` where the m is abstract) *you don't _need_ to know "what it is actually doing" - it should be correct for any choice of* `m`.

      The behavior, and the "laws" or perhaps general far-reaching properties, are the more important part of Monads I think.

      > How does that relate to “pipe operator” as in https://github.com/tc39/proposal-pipeline-operator

      The items in the pipeline don't have a set of laws that let you know what's going on for sure without looking at the implementation I guess.

    • leshowMar 2019

      Have a look at this blog post, it contains the bit I got that fold description from:

      https://philipnilsson.github.io/Badness10k/algebraic-patterns-monoid/

      Back to my first post, I don't think it's not wrong to describe these operations as monoidal. Or to say that a monoidal operation implies something can be run in parallel, this whole thing feels a bit pedantic.

      edit: I don't know how you can say monoids for lists have nothing to do w/ empty lists considering the definition is literally:

      -- Identity laws
      x <> mempty = x
      mempty <> x = x

      Which is exactly what I posted before

    • solaticAug 2020

      Everything old is new again. This challenge is basically why monads exist, because the monad allows you to cleanly separate between the state in which the algorithm is running and the algorithm itself. Reminds me of: https://philipnilsson.github.io/Badness10k/posts/2017-05-07-escaping-hell-with-monads.html

      I wonder what poor abstraction the Go authors will come up with instead?

    Related

    Haskell for Allhaskellforall.com190 people

    The category design pattern

    Haskell for All
    Personal · last shared 2026
    Jeremy Bowersjerf.org78 people

    Functors and Monads for People Who Have Read Too Many “Tutorials”

    Jeremy Bowers
    Personal · last shared 2026
    John A. De Goesdegoes.net81 people

    Twitter's Fucked

    John A. De Goes
    Personal · last shared 2026
    Apfelmusapfelmus.nfshost.com22 people

    How Does Lazy Evaluation Work in Haskell? (2014)

    Apfelmus
    Personal · last shared 2023
    Matt Parsonsparsonsmatt.org57 people

    Write Junior Code

    Matt Parsons
    Personal · last shared 2026
    Mark Seemannblog.ploeh.dk171 people

    From Design Patterns to Category Theory (2017)

    Mark Seemann
    Personal · last shared 2026
    Luke Palmerlukepalmer.wordpress.com35 people

    IDE WTF

    Luke Palmer
    Personal · last shared 2020
    Lambda the Ultimatelambda-the-ultimate.org615 people

    Simon Peyton Jones Elected into the Royal Society Fellowship

    Lambda the Ultimate
    Publication · last shared 2026