Monday Morning Haskell
mmhaskell.com · Company blog · on HN since 2017
Monday Morning Haskell publishes Haskell tutorials and project walkthroughs, covering topics like monad transformers, string types, parsing, and Rust for Haskell programmers.
What HN saysCommenters point to it as the best intro to monad transformers and as a source of worked examples for doing practical tasks in Haskell.
26HN people shared it
11linked it in comments
27stories submitted
327story points
12 months agolast shared
2017people per year2026
Most-shared posts
- 1Untangling Haskell's Strings3 people · 2 points · first shared 2018 · discussion on HN
- 2Binary Packet Parsing2 people · 19 points · first shared 2022 · discussion on HN
- 3A Project in Haskell: One Week Apps2 people · 9 points · first shared 2017 · discussion on HN
- 4The Future Is Functional: Haskell and the AI-Native World2 people · 8 points · first shared 2017 · discussion on HN
- 5Rust for Haskell Programmers2 people · 5 points · first shared 2021 · discussion on HN
- 6Blog2 people · first shared 2018
- 7Test driven development2 people · first shared 2022
- 8Real World Haskell1 people · 218 points · first shared 2020 · 77 comments on HN
- 9Zoom and Enhance1 people · 21 points · first shared 2022 · 2 comments on HN
- 10Dijkstra with Type Families1 people · 12 points · first shared 2022 · discussion on HN
- 11Generalizing Dijkstra's Algorithm1 people · 4 points · first shared 2022 · discussion on HN
- 12Starting Out with Haskell Tensor Flow1 people · 4 points · first shared 2017 · discussion on HN
- 13Dijkstra's Algorithm in Haskell1 people · 4 points · first shared 2022 · discussion on HN
- 14Parsing an HTTP Request – Monday Morning Haskell1 people · 3 points · first shared 2025 · discussion on HN
- 15Identity: Using the Identity Monad1 people · 3 points · first shared 2021 · discussion on HN
What HN people wrote when they linked it
chuckadams · 2024-06-17
> My favorite example of this is implementing quicksort. It's significantly easier in C than it is in Haskell.
Oh please, what's so hard about
qsort :: Ord a => [a] -> [a] qsort [] = [] qsort (p:xs) = qsort lesser ++ [p] ++ qsort greater where lesser = filter (< p) xs greater = filter (>= p) xs :)
folks, take that with a big ol /s, you would never want to actually use that algorithm. But the real deal isn't all that awful: https://mmhaskell.com/blog/2019/5/13/quicksort-with-haskell
ghostwriter · 2019-10-06
The best intro to monad transformers that I've seen so far is https://mmhaskell.com/monads/transformers
zorkw4rg · 2018-10-06
I'm not so sure other languages do that any better (nodejs doesn't even support non-unicode filenames at all for instance). Modern python does a pretty good job at supporting unicode, very far away from being a "Mess" that's just very much not true at all. People always like to hate on python but then other languages supposedly designed by actually capable people do mess up other stuff all the time. Look at how the great Haskell represents strings for instance and what a clusterfuck[1] that is.
[1] https://mmhaskell.com/blog/2017/5/15/untangling-haskells-strings
embwbam · 2020-10-19
This looks well done, but having used Haskell professionally on multiple web projects, I have to take issue with some of the design choices.
Templating? Haskell provides such a wonderfully clean way to generate HTML via combinators and do notation. You don't need a quasi quoter to get a DSL. See Lucid. All templating does is remove control features (like forM, for example). [1]
They've reinvented common operators. For example, (|>), which is great, I've used it in Elm, but the Haskell version of this is (&) from Data.Function.
These are just a few examples. They're ignoring Haskell conventions to make it more familiar to people coming from other backgrounds, even when the community conventions are strictly better or equal. Rails was a nightmare for me, it was impossible to tell what was a language feature and what came from the framework. I suspect this will equivalently speed up initial development while slowing understanding.
[1] https://mmhaskell.com/blog/2020/3/16/lucid-another-html-option
cosmic_quanta · 2025-11-02
That is a really tough spot to be in. I don't know of any content that's aimed at someone like you.
You might be interested in reading the Monday Morning Haskell blog[0] series, which presents examples of how to do certain tasks in Haskell. See [1] for an example.
[0]: https://mmhaskell.com/blog
[1]: https://mmhaskell.com/blog/2025/5/19/comparing-code-leetcode-problems-…
nine_k · 2023-01-06
Don't $ signs work in Nix the way the work in Haskell?
E.g. https://mmhaskell.com/blog/2021/7/5/function-application-using-the-dol…
jokethrowaway · 2022-06-08
HUnit is a popular choice: https://mmhaskell.com/testing/test-driven-development
sctb · 2018-06-26
Are you already familiar with GHC? If not, the “Contributing to GHC” series might be helpful: https://mmhaskell.com/blog/.
allenleein · 2017-09-02
If you want to learn Haskell or functional language:
Haskell for all- http://www.haskellforall.com/
Bryan O'Sullivan's blog- http://www.serpentine.com/blog/
Monday Morning Haskell- https://mmhaskell.com/
Jane Street- https://blog.janestreet.com/
Haskell Weekly- https://haskellweekly.news/
Neil Mitchell's Haskell Blog-http://neilmitchell.blogspot.tw/
Types & Functional Programming- http://bitemyapp.com/
Haoyi's Programming Blog- http://www.lihaoyi.com/post/WhatsFunctionalProgrammingAllAbout.html
trealira · 2024-08-09
You can also use it for representing errors, for representing global read-only variables, for representing global write-only variables, for representing non-determinism, for representing continuations, and other things (since you can write your own).
For example, this is a really minimalistic arithmetic syntax tree interpreter in Haskell. You could write errors using the Either type:
data Term = Constant Int | Divide Term Term eval :: Term -> Either String Int eval (Constant n) = n eval (Divide left right) = case eval left of Left errorString -> Left errorString Right leftResult -> case eval right of Left errorString -> Left errorString Right rightResult -> if rightResult == 0 then Left "Division by zero" else Right (div leftResult rightResult) It's cumbersome, and there's a staircase growing. Because Either is a monad, you could rewrite the division op like this:
eval (Divide left right) = do leftResult <- eval left rightResult <- eval right if rightResult == 0 then Left "Division by zero" else Right (div leftResult rightResult) This is a good article about the either monad: https://mmhaskell.com/blog/2022/3/3/using-either-as-a-monad
The state monad is basically a wrapper over a pure function that takes a state and returns a tuple with the result and a new state. In an imperative language, you'd just actually change state, rather than doing…
ParetoOptimal · 2022-06-08
This comment has a lot of facts wrong.
> Even if a library works, debugging edge cases is never thought of.
Many libraries use sum types to express their api which naturally leads one to consider edge cases.
> Almost nothing is written about testing in Haskell.
Yes there is! Did you verify your claim with a quick search? Here's what one gave me:
- https://mmhaskell.com/testing/test-driven-development
-
https://jaspervdj.be/posts/2015-03-13-practical-testing-in-haskell.htm…
Heck, here's one from 2007:
https://www.jasani.org/posts/2007/unit-testing-with-hunit-in-haskell/
It feels like this web of lies about Haskeller's not caring about real world concerns is being spun, but even with minimal effort that is trivial to disprove.
> No two libraries can agree on which monad stack to use,
The mtl library is the most used monad stack by far and it's not typical to see others very often.
> so a non-trivial amount of integration code involves matching and lifting into other monads (nor the performance implications of doing all of this matching and lifting).
I feel this may betray a lack of understanding because lifting between monad stacks is expected.
I agree there are performance implications on theory, but if you get out of the performance ivory tower you'll find it doesn't happen much in the real world ;)