In Haskell, find is designed to evaluate as a Maybe, because when scanning a list for an element matching a predicate, it could fail. However, consider the following:
factorize n | isPrime n = [n]
| otherwise = m : factorize (n `div` m)
where m = find ((==0) . (n `mod`)) [2..]
find here will clearly find a value in every case, assuming we’re only hitting integers greater than 2. If a number is not prime, then it has a factor somewhere in the infinite list [2..]. But of course, Haskell doesn’t know that, and will still complain that a Maybe is being used. What is the solution here?
- Use
fromMaybewith some dummy default value to extract the inner value. The default value will never be used. - Use something like
head . dropWhileto act as a kind of “unsafe find”. - Bubble the Maybes all the way up and have the factors returned as a list of Maybes.
- Some way to tell Haskell “look, the math checks out, this is safe, just trust me.”
1 and 2 are smelly, 3 is cumbersome and adds failure state to a function it shouldn’t exist in, and I don’t know whether 4 exists. What is the best solution here?
Edit: The above list of options is incomplete without mentioning fromJust, which takes a Just and returns the value inside it, and throws an error when given a Nothing. I think that's clearly the short answer to my question, and I wasn't aware of its existence until I read the answers and comments here. However, there are still good points made about safety and fail state in general in the answers below.