Justin Le
blog.jle.im · Personal blog · on HN since 2013
Justin Le writes about Haskell, functional programming, dependent types and applying them to physics and machine learning.
What HN saysCommenters point to his posts as clear explanations of functors and monads, typed models, fixed-length vectors and Hamiltonian dynamics in Haskell.
36HN people shared it
16linked it in comments
40stories submitted
426story points
3 months agolast shared
2013people per year2026
Most-shared posts
- 1IO Monad Considered Harmful5 people · 93 points · first shared 2015 · 74 comments on HN
- 2Functors to Monads: A Story of Shapes3 people · 43 points · first shared 2024 · 7 comments on HN
- 3Haskell Nuggets: K-Means3 people · 13 points · first shared 2024 · discussion on HN
- 4The Baby Paradox in Haskell3 people · 12 points · first shared 2025 · 1 comments on HN
- 5Shuffling Things Up: Solving Advent of Code with Group Theory and Haskell3 people · 5 points · first shared 2020 · discussion on HN
- 6Purely Functional Approach to Typed Trainable Models3 people · 4 points · first shared 2018 · 1 comments on HN
- 7Hamiltonian Dynamics in Haskell3 people · 3 points · first shared 2017 · discussion on HN
- 8Typesafe Neural Networks in Haskell with Dependent Types2 people · 145 points · first shared 2016 · 18 comments on HN
- 9First Class Statements2 people · 48 points · first shared 2015 · 13 comments on HN
- 10Faking ADTs and GADTs in Languages That Shouldn't Have Them2 people · 8 points · first shared 2025 · discussion on HN
- 11Sum Types and Subtypes and Unions2 people · 4 points · first shared 2025 · 1 comments on HN
- 12Io monad considered harmful2 people · first shared 2019
- 13Inside My World – Ode to Functor and Monad1 people · 12 points · first shared 2014 · 4 comments on HN
- 14Solving Advent of Code Day 5 w Group Theory (free groups, group homomorphisms)1 people · 4 points · first shared 2018 · discussion on HN
- 15Seven Levels of Type Safety in Haskell: Lists1 people · 4 points · first shared 2024 · discussion on HN
What HN people wrote when they linked it
not-a-llm · 2026-07-13
talking about data and function shapes is quite common in functional programming world
https://blog.jle.im/entry/functors-to-monads-a-story-of-shapes.html#a-…
mjaniczek · 2021-08-16
> No mon[a|oi]ds necessary.
Mon[a|oi]ds are everywhere, but in some languages you just don't know about it. Which of course lets you not have to learn those concepts knowingly, but they're still there and you still could be a better developer for at least knowing they're there and they're behind some of the repeating patterns you see (string concatenation / promises / etc.)
I believe "not worrying about them at first" is actually a good path to learn these patterns. Using them first, some time later having a thought "oh hey, the API of how JSON decoders are written is kinda similar to how I'm generating random values, that's cool" and only later on learning that the it is in fact monads/monoids/functors/whatever and that they have laws and you can exploit that (eg. [repeated squaring for anything that's a semigroup](https://blog.jle.im/entry/shuffling-things-up.html)) and whatnot.
pseudonom- · 2021-02-01
To the extent that I understand your complaint, there is a functional architecture that alleviates this concern: arrowized functional reactive programming. https://blog.jle.im/entry/intro-to-machines-arrows-part-1-stream-and.h… talks about it.
formalsystem · 2019-11-06
I don't think the Julia implementation makes much use of typing. A related Haskell codebase for Hamiltonian (not Lagrangian) mechanics that I found really helpful to scan was https://blog.jle.im/entry/hamiltonian-dynamics-in-haskell.html -
almostdeadguy · 2019-06-09
You can have types in haskell that represent finite length lists. Here's a blog post giving an overview of several methods of doing so (and several examples of libraries in the wild that provide this): https://blog.jle.im/entry/fixed-length-vector-types-in-haskell.html
There's a tradeoff here between generality and how important it is to encode all invariants about a piece of data. Many haskell list processing functions are expressed in terms of right folds, which makes infinite lists fairly unproblematic to work with so long as only part of the list is demanded in the end, however for some cases you may want the type system to ensure you can't receive an infinite list.
mormegil · 2019-02-11
In other words, IO Monad Considered Harmful. https://blog.jle.im/entry/io-monad-considered-harmful.html
unhammer · 2018-01-08
See https://blog.jle.im/entry/practical-dependent-types-in-haskell-2.html where you get this function definition: https://github.com/mstksg/inCode/blob/master/code-samples/dependent-ha…
I liked this article: https://ren.zone/articles/safe-money where they get e.g. an ExchangeRate "USD" "JPY" type from input that has a different type from ExchangeRate "EUR" "JPY" (and thus can't be used to convert euros, only US dollars).
KirinDave · 2018-01-07
Folks who are into this may also like the "Type Safe Neural Networks in Haskell" https://blog.jle.im/entry/practical-dependent-types-in-haskell-1.html
I'm also starting work on a set of bindings to libdarknet for Idris with similar properties.
wz1000 · 2015-05-18
Here's an explanation of how IO works in Haskell: http://blog.jle.im/entry/first-class-statements
If you go through it and understand it, you will find that it is completely "pure".
kenko · 2015-05-11
He even says explicitly "(never mind how we deal with uniqueness)" in the solution section and has already acknowledged that there are only around 2 million combinations to check.
ETA since he mentions the implementation is a translation of this Haskell implementation: http://blog.jle.im/entry/unique-sample-drawing-searches-with-list-and-… presumably the uniqueness is done by updating the list of remaining possibilities for selection each time a new value is selected.
codygman · 2015-03-10
platz · 2015-02-17
This post builds the intuition for something like the Netwire library
http://blog.jle.im/entry/effectful-recursive-real-world-autos-intro-to…
yawaramin · 2015-02-15
In truth, you don't actually have to climb the IO monad learning curve. IO in Haskell has nothing to do with monads.[1] It's simply a type which encodes input and output effects. Simple and elegant. The fact that people so thoroughly confuse the issue by mixing the disparate topics of IO and monads, is a shame.
[1] http://blog.jle.im/entry/io-monad-considered-harmful
Twisol · 2023-09-25
You don't need to understand monads to do IO. From [0]:
> There is nothing that has to do with monads at all in printing a string. The idea that `putStrLn "hello world"` is monadic is as absurd as saying that `[1,2,3]` is monadic.
You haven't linked any exemplar tutorials, but I feel confident in saying the ones you're referring to teach the general concept of monads, and not how to do IO with monads.
Quite a number of JavaScript developers learned how to use `andThen` with Promises/A+ back in the day, and they didn't need to learn about monads either. (In fact, when it was raised that promises are really monads, there was serious drama and outrage [1] -- an existence proof if there ever was one, that you can use something productively without understanding it as a monad.)
Likewise, nobody would claim that you need to understand monoids before you can concatenate lists. Concatenating lists is as native to lists as sequencing commands is to IO; it's just part of how those types work. The monad interface abstracts over that idea, and learning that abstraction in its full generality is, typically, what people stumble on.
[0]: https://blog.jle.im/entry/io-monad-considered-harmful.html
[1]: https://github.com/promises-aplus/promises-spec/issues/94
jarcane · 2015-07-01
Don't get me wrong; I'm not knocking it. I definitely see the value in these kinds of features.
Like zippers, I'm sure it's another case of "If you understand it, it's really useful."
The point is, you don't necessarily need it to get the job done, and you certainly don't need to be intimidated about it or feel obligated to learn it right off.
Even Haskell isn't actually so difficult to grasp the basics of, if you keep this in mind and just think "Do IO in a 'do' block" and go about your way. See [1].
You don't have to know everything in any language just to get some work done, a lot of times advanced features are just that: advanced, stuff for doing things a bit more efficiently, or to handle certain rough edge cases. Learn them in their own time, and they'll make you better at what you do, but don't get wrapped up too much in expecting perfect efficiency from yourself.
A lot of programmers seem to be, as a people, kinda bad at this kind of self-reflection, like we're all sheep in wolves' clothing trying to avoid showing a hint of weakness. I know I sure am. There's nothing wrong with not knowing something, just try and take a moment learn it when you can.
[1] http://blog.jle.im/entry/io-monad-considered-harmful