4 ms·
How does the error case break the monadic model? All of the monad rules still apply, I think.
by eximius 7y ago
How does the error case break the monadic model? All of the monad rules still apply, I think.
- pinopinopino 7y agoThe error needs to be a monoid to be able to flatten the Result, if it is not, it will break, you will lose information. E.g. if you have: R<E1,R<E2,A>> -- flatten --> R<E1 + E2, A> R stands for result, E1,E2 are errors. You need to think up a reasonable implementation of +. This is of course easily solvable, you can just add them together. Keep a list of errors in your result instead of one error and you are done. Just keep the +, it is free :p
- lmm 7y agoThis is completely wrong. Result is either success or failure, so an R<E1, R<E2, A>> can never contain both E1 and E2 at the same time. Validation types work the way you describe and require a monoidal "error" side, but famously do not form monads (though they are applicative functors).
- pinopinopino 7y agoA true that, long day and have been working with shapeless in scala, where type level and value level mixes up :)
- eximius 7y agoWhile compelling, flattening doesn't make something a monad, does it? Not snark, if that's a consequence of one of the three laws, I'm just unaware of it. I know what monads are but I'm not practised with them. But of left identity, right identity, and associativity, what is violated?
- pinopinopino 7y agoSo, I was a bit wrong with the monoid, I meant to add them on typelevel by using a sumtype. Sorry, sometimes bit confused after work. No flattening doesn't make something a monad. Return and flattening are the interesting operations of a monad, that together with the laws makes the monad. >But of left identity, right identity, and associativity, what is violated? Well, there is not something violated perse, but you cannot write a flatten operation for something like this: R<R<u32, E1>, E2> However you could write it for this: R<R<u32, E1 + E2>, E1 + E2> (That was what I should have written above btw) Because now the error types are the same.
- bcheung 7y agoI created a Result style interface in Typescript and made the decisions to fix the Error to a single type for this very reason. Result<T> instead of Result<T,E> so that it was easier to compose. This made Kleisli composition easier since I don't have to worry about mismatched types on the Error. You can see the code at https://github.com/brennancheung/wasmtalk/blob/master/src/fp/Result.ts https://github.com/brennancheung/wasmtalk/blob/master/src/fp...
- whelming_wave 7y agoI've found this kind of pattern much nicer in an application context. Rust sort of has this going on with anyhow[1] for applications and thiserror[2] for libraries (or just writing your own Error type). [1]: https://crates.io/crates/anyhow https://crates.io/crates/anyhow [2]: https://crates.io/crates/thiserror https://crates.io/crates/thiserror