Usage of partial functions (functions that may not return a value) is generally discouraged. Functions like head
and fromJust
exist because they're occasionally convenient; you can sometimes write shorter code, which is more understandable to learners. Lots of functional algorithms are expressed in terms of head
and tail
and fromJust
is conceptually the same as head
.
It's usually preferable to use pattern matching, and to avoid partial functions, because it allows the compiler to catch errors for you. In your code snippet you have carefully checked that the value is never Nothing
, but in large real-life codebases, code can be many years old, 1000's of lines long and maintained by many developers. It's very easy for a developer to re-order some code and miss out a check like that. With pattern-matching, it's right there in the code structure, not just in some arbitrary Bool expression.
It's not too difficult to replace your usage of fromJust
with pattern-matching:
answer26 = answer26' 1000
answer26' n = snd $ maximum $ map (\x -> cycleLength x [1]) [2..n - 1]
where
cycleLength n (r:rs) = case elemIndex r rs of
Just i -> (1 + i, n)
Nothing -> if r < n
then cycleLength n $ (10*r):r:rs
else cycleLength n $ (r `mod` n):r:rs
And (I think) the result is a bit clearer too.
Edit: There's an apparently "theoretically ok" place to use fromJust
mentioned in Typeclassopedia, though you will need someone other than me to explain wtf that is all about.. ;)