|
|
|
|
|
by Rusky
3025 days ago
|
|
> (granted, there is some ground to be covered before such an abstraction would fit in Rust) I would claim that such an abstraction is fundamentally incompatible with Rust. Not only does Rust lack the means to write a Monad trait on which to build do-notation, but even given HKT there's no single type signature that the various monad instances would fit. `Result` and `Option` are type constructors while `Iterator` and `Future` are generic traits; some instances require `Fn` or `FnMut` while others require `FnOnce`. And even assuming those problems could be solved, the way do-notation interacts with control flow is not composable with idiomatic Rust. Nested closures prevent the use of return/break/continue and imperative loops; Haskell doesn't have those features so people just lift their functional counterparts into monads. Monad transformer stacks make the situation even worse- they are a pain to compose even with each other, let alone imperative code. If you want a unifying mechanism for this stuff in Rust it's gonna need to be fundamentally more powerful than monads. Scoped continuations, maybe? Certainly nothing that looks like >>=. |
|
There are more convenient ways of composing monads than monad transformers; extensible effects are a lot easier to work with.
Ulttimately I agree though, monads are not the right abstraction for a systems language. I'm quite happy using them in languages like Haskell and OCaml, where you've not only got a garbage collector solving the tricky ownership qustions for you, it's also faster than it has any right to be, so you can basically ignore the overhead of heap allocating a closure.
They become much less attractive when you're in a problem domain where you actually want to worry about fiddly details around memory allocation. This is much smaller space than people think it is, but it's what Rust is for.