Monday Morning Haskell publishes Haskell tutorials and project walkthroughs, covering topics like monad transformers, string types, parsing, and Rust for Haskell programmers.
Commenters point to it as the best intro to monad transformers and as a source of worked examples for doing practical tasks in Haskell.
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…
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.html
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 ;)
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
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
> 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
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