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

whispers in monads

It can be done "functionally" but doesn't necessarily have to be done in an FP paradigm to use this pattern.

There are other strategies to push resource handling to the edges of the program: pools, allocators, etc.





Right, but even in those, you typically have the more imperative operations as the lower levels, no? Especially when you have things where the life cycle of what you are starting is longer than the life cycle of the code that you use to do it?

Consider your basic point of sale terminal. They get a payment token from your provider using the chip, but they don't resolve the transaction with your card/chip still inserted. I don't know any monad trick that would let that general flow appear in a static piece of the code?


> but even in those, you typically have the more imperative operations as the lower levels

Yes, the monadic part is the functional core, and the runtime is the imperative shell.

> Consider your basic point of sale terminal. They get a payment token from your provider using the chip, but they don't resolve the transaction with your card/chip still inserted. I don't know any monad trick that would let that general flow appear in a static piece of the code?

What do you mean by Monad trick? That's precisely the kind of thing the IO monad exists for. If you need to fetch things on an API: IO. If you need to read/save things on a DB: IO. DB Transaction: IO.


I have not seen too many (any?) times where the monad trick is done in such a way that they don't combine everything in a single context wrapper and talk about the "abnormal" case where things don't complete during execution.

Granted, in trying to find some examples that stick in my memory, I can't really find any complete examples anymore. Mayhap I'm imagining a bad one? (Very possible.)


You would deal with this problem in the same way you would with, say, in a REST API.

If the transaction object is serializable you can just store it in a DB, for example. If it's some C++ pointer from some 3rd-party library that you can't really serialize and gotta keep open, you gotta keep it in memory and manage its lifetime explicitly, be it a REST web server, in Haskell or in a C++ app.


Right, I think a better way of stating my main assertion here is that you have to be able to partially work in a transaction. If your "shell" pretends that you can always complete the full transaction, either successfully or with a failure, then it is a brittle shell. Sometimes, you can simply make progress on an presumed open transaction.

It doesn’t have to pretend anything you don’t want. If you don’t want this kind of problem/failure possibility, then you have to encode those states in the type system. Functional programming can do the same things you can do in imperative, but you gotta make it when it’s not there. Just like in any other paradigm.

Totally fair. As I said up thread, I am comfortable saying I am imagining bad examples here. Would be interested in reading good examples. Though I couldn't find any of the bad ideas I had in my mind, I also didn't find any good ones on a quick search.

I'm unclear what you're suggesting here. Are you suggesting you couldn't write a POS in Haskell, say?

My idea here is that, in many domains, you will have operations that are somewhat definitionally in the imperative camp. OpenTransaction being the easy example.

Can you implement it using functional code? Yes. Just make sure you wind up with partial states. And often times you are best off explicitly not using the RAI pattern for some of these. (I have rarely seen examples where they deal with this. Creating and reconciling transactions often have to be separate pieces of code. And the reconcile code cannot, necessarily, fallback to create a transaction if they get a "not found" fault.)




Consider applying for YC's Winter 2026 batch! Applications are open till Nov 10

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

Search: