4 ms·
Curious; why `Maybe (Stack a, a)` rather than `(Stack a, Maybe a)`? The returned stack would be empty like the input.
by wool_gather 6y ago
Curious; why `Maybe (Stack a, a)` rather than `(Stack a, Maybe a)`? The returned stack would be empty like the input.
- uryga 6y agoi guess it's "making illegal states unrepresentable" – with `(Stack a, Maybe a)` you allow an implementation that does stackPop [1,2,3,4] == ([1,2,3], Nothing) which doesn't make sense - `Nothing` is only supposed to happen when the stack is empty, i.e. `([1,2,3], Nothing)` should be impossible. and if `([], Nothing)` is the only "error state", why not just use a `Nothing` for the whole thing instead? and then you can sleep soundly, knowing your pattern-matches are exhaustive :) ergonomically, it's nicer to to test for failure; and you can do "railway-oriented programming", either doing something with the result or quickly bailing out. all that said, there's probably cases where `(Stack a, Maybe a)` is more ergonomic... so you know, this isn't dogma
- wool_gather 6y agoErgonomics could be the reason; good point. I don't think your first point is correct, though; nothing about `Maybe (Stack a, a)` stops me returning `Nothing` incorrectly.
- uryga 6y agoi was going to mention this, but the comment was already long :) of course, this doesn't stop you from implementing it as stackPop _ = Nothing or just doing the wrong thing. but it does prevent you from returning `([1,2,3], Nothing)`, and that's always one less thing to worry about - if not for the implementer, then for the users. and the more the signature constrains possible implementations¹, the better! and this might be subjective, but for me `Maybe (Stack a, a)` results in less cognitive load. with `(Stack a, Maybe a)` if i do case stackPop xs of (_, Nothing) -> ... (xs2, Just x) -> ... in the back of my head i'm going to be thinking "hmm, am i 100% sure i can throw away that first value if i get a Nothing in there? if it's useless, why does the function return it?²" whereas with case stackPop xs of Nothing -> ... Just (xs2, x) -> ... i know for certain there's no new values introduced in Nothing case – great, less things to keep in my head! it's a small thing to be sure, but i like when the types assist me like this :) --- ¹ parametricity is one of my favorite things in pure FP! ² but i hate throwing things away, so it might just be that...