4 ms·
I may have been slightly misleading if I implied "isJust" is unsafe. It is perfectly safe. What's unsafe is "fromJust" which crashes at runtime if the Maybe val
by Peaker 14y ago
I may have been slightly misleading if I implied "isJust" is unsafe. It is perfectly safe. What's unsafe is "fromJust" which crashes at runtime if the Maybe value is in fact a Nothing. "isJust" is code-smell because it means you're likely to need a "fromJust" later.
The problem is: What if the condition is changed later? What if you use "fromJust" in the else branch? What if the code is moved around outside of the condition's scope?
The above is meant to illustrate that the "isJust/fromJust" anti-pattern is out-and-out unsafe. You get no compile-time assurances. If you avoid "fromJust" altogether (and equivalent constructs, of course), you have a 100% guarantee that you will not crash from expecting a Just where there's a Nothing (IOW, nil dereference).
Additionally, "Just" and "Nothing" are data constructors (can be viewed as value tags) within the Maybe type, they are not "types" themselves.
Except for these points, I think you are generally describing it correctly.
This kind of thing (avoiding boolean blindness) as well as a few more safety nets in Haskell is the reason lots of Haskell code is said to Just work once it compiles.
- wonderzombie 14y agoOK, yes, I can see how `fromJust`, more specifically, is the unsafe part. You're dereferencing a pointer which is probably non-nil but the compiler can't tell you because you've insisted on checking it manually rather than communicating your intent to the compiler more directly. So when you say "avoid fromJust," the alternative in practice is to use pattern matching, yes? The example you used above was a case statement. A guard clause is another obvious one, as are additional clauses (?) in a function.
- Peaker 14y agoThere are many alternatives to fromJust. They are all essentially implemented on top of the safe primitive: pattern-matching. Guard clauses in Haskell are actually boolean conditionals, and are boolean-blind. Safe pattern-matching can be done via the function definition sugar: f Nothing = ... f (Just x) = ... Which is equivalent to a "case". The various functions that work with a Maybe value make it non-tedious to do things. For example, instead of: case mx of Just x -> Just (x + 1) Nothing -> Nothing You can write: fmap (+1) mx Additionally, (>>=), fromMaybe and many other useful functions exist, and they're all based on safe pattern-matching.