Reputation: 4119
I am currently working with quite dirty project written in Haskell. It contains lots of code like:
try_parse_parameters (p:ps) kvps options =
let maybeKvp = try_parse_kvp p
in
if isJust maybeKvp
then try_parse_parameters ps ((fromJust maybeKvp) : kvps) options
else
let maybeOption = try_parse_option p
in
if isJust maybeOption
then try_parse_parameters ps kvps ((fromJust maybeOption) : options)
else try_parse_parameters ps kvps options
Thus, my questions is: is there some standard method(s) to deal with such a situation?
Upvotes: 2
Views: 89
Reputation: 749
You can also handle more than one case with pattern matching, avoiding the pyramid of doom.
try_parse_parameters (p:ps) kvps options =
case (try_parse_kvp p, try_parse_option p) of
(Just k, _) -> try_parse_parameters ps (k : kvps) options
(Nothing, Just o) -> try_parse_parameters ps kvps (o : options)
(Nothing, Nothing)-> try_parse_parameters ps kvps options
Upvotes: 5
Reputation: 16645
Yes, what you're looking for is called pattern matching, and you can't really write haskell without it. Here's the most straightforward adaptation of your code:
try_parse_parameters (p:ps) kvps options =
case try_parse_kvp p of
Just kvp -> try_parse_parameters ps (kvp : kvps) options
Nothing ->
case try_parse_option p of
Just o -> try_parse_parameters ps kvps (o : options)
Nothing -> try_parse_parameters ps kvps options
From here there are a lot of things you might improve, now or later as you learn more haskell:
foldr
to factor out the recursion and make it more clear to people reading your code what it does (and what it can't do; i.e. making it easier to reason about)Alternative
class is helpful, or using a monadic fold perhaps if you want the entire computation to fail if any of the parses fail completelyUpvotes: 4