4 ms·
A mistake easily corrected. They do convey the exact meaning well. It's the analogy that appeals to your intuition which is wrong. Either a b === a || b W
by agentultra 7y ago
A mistake easily corrected. They do convey the exact meaning well. It's the analogy that appeals to your intuition which is wrong.
Either a b === a || b
Where `===` means equivalent to. This means that a value of the type can hold either the `a` or the `b`. In order to construct a value of this type you used the `Left` function to construct a value contain the value on the left side of the operator and Right for the other side.
They have no "semantics" otherwise. You could call them "Jib" and "Jab," and it'd amount to the same thing. Simply because you ascribe a particular meaning doesn't change their nature. Hence why Left and Right.
Now I do recommend, for readability's sake, ascribing an alias to this type if it aids your understanding of the code when you use it in a particular way that gives your code a certain meaning!
- switchbak 7y agoI think they're saying he would prefer some semantics - like one is the preferred or normal case, and the other is an error or unexpected case. They might convey the exact meaning well, but they (and I) would prefer a type with slightly different semantics that better remind us what each side actually represents.
- erikpukinskis 7y agoDid you catch about what OP was saying though? Instead of Normal and Unexpected they are recommending you write something like: const ChargeSuccess = Left const ChargeDeclined = Right And then use that language in your code. Those words tell you something about the semantics of the code being wrapped. “Normal” and “Error” don’t actually mean much. Also, you might want to someday write: const NormalDelivery = Left const FastTrack = Right And that wouldn’t make much sense if fast track is a so-called error condition.
- switchbak 7y agoI did see that. This is a common pattern in many functional languages, and (for example) Scala has the same issue with Either. It's a common enough complaint that there are numerous right-biased utility versions in the wild that make it more ergonomic. Having a type that is right biased doesn't mean it can't also implement the more generic interface. If your needs change you can always go back to using the less opinionated version with little breakage. Rust's is notable in that they have both Either and Result. I think there's value in that, even if it is mainly for ergonomics and communication. Also, aliases are fine, I could just see them being duplicated a lot. Probably not my first choice.
- leshow 7y ago> Rust's is notable in that they have both Either and Result. I think there's value in that, even if it is mainly for ergonomics and communication. either isn't in std though, it's a third party crate. Personally, I think the core data structure should be as generic as possible. The reality is that if the Result type was named appropriately, the Either crate would be redundant.
- ChrisSD 7y agoRust's "generic as possible" type is an enum. Result is a specialization meant for common error handling.
- leshow 7y ago> Rust's "generic as possible" type is an enum What enum? We're talking about a specific data type, it doesn't make any sense to say 'an enum' is the generic version of Result. I understand why they chose Result instead of Either. I just disagree with it; what you end up with is 2 data structures with the exact same structure and implementations but that represent different things. If you have Either in std, then Result is redundant, but not the other way around.
- ChrisSD 7y agoWhat Result? Result is a generic not a specific type. It's essentially a shorthand instead of manually writing out the enum yourself. More fundamentally I disagree that Either makes Result redundant. Result has semantic meaning that's lost with Either.
- leshow 7y ago> What Result? Result is a generic not a specific type. It's essentially a shorthand instead of manually writing out the enum yourself. No, it's not 'a generic', but it has generic type parameters. An enum can be any number of variants with any number of type parameters. A result is: data Result a b = Err a | Ok b (or in Rust) enum Result<T, E> { Err(E), Ok(T) } > It's essentially a shorthand instead of manually writing out the enum yourself. I'm not sure which enum you're referring to. You do realise an enum can have any number of variants, not just 2? I could define a sum type with 16 variants. 'enum' is just Rusts keyword for defining sum types. > Result has semantic meaning that's lost with Either. Which is what?
- jeremyjh 7y agoThere definitely are more semantics than this in the monad instance for Either, which treats Left as "failure" (via early exit in a comprehension) and Right as "success". The docs call out the convention as well.
- deleted 7y ago[deleted]
- derefr 7y agoOr, to put that another way, Either is "cons" for types, and you can build up a sum type as a type-level linked list of types by repeatedly "cons"ing (Either-ing) types together: (a || b || c || ...). The functional-programming traditionalist would call the type-level "slots" of an Either its "CAR type" and "CDR type". But, since there's no abstraction that assumes that such a structure of sum-types is shaped like a proper list, there's nothing stopping you from building any arbitrary binary tree of types using Either. And so, like any other binary tree, the two branches get called Left and Right.