Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to optimise a nested pattern match with multiple repeated cases?

Please consider this code:

case action1 of
  Right a -> a
  Left (Failure1 a) -> a
  Left (Failure2 a) -> 
    case action2 a of
      Right a -> a
      _ -> error "Unexpected failure"
  _ -> error "Unexpected failure"

You can see that I have to repeat myself twice: with the Right and with the error cases.

How can I optimise this? Is it possible at all?

like image 770
Nikita Volkov Avatar asked Jun 21 '13 06:06

Nikita Volkov


2 Answers

That's a good application for pattern guards:

case action1 of
  Right a -> a
  Left f
    | Failure1 a <- f       -> a
    | Failure2 a <- f
    , Right b <- action2 a  -> b
  _ -> error "Unexpected failure"
like image 200
leftaroundabout Avatar answered Nov 09 '22 14:11

leftaroundabout


I'd put the error handling part outside the case part:

fromMaybe (error "Unexpected failure") $
    let eitherToMaybe = either (const Nothing) Just
    in case action1 of
          Right a           -> Just a
          Left (Failure1 a) -> Just a
          Left (Failure2 a) -> eitherToMaybe (action2 a)
          _                 -> Nothing
like image 4
Petr Avatar answered Nov 09 '22 14:11

Petr