2013-06-21 2 views
8

Пожалуйста, обратите внимание этот код:Как оптимизировать совпадение вложенного шаблона с несколькими повторяющимися случаями?

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" 

Вы можете видеть, что я должен повторяться дважды: с Right и с error случаев.

Как это можно оптимизировать? Это вообще возможно?

+2

Вашей слежки переменный 'a' не так хорошо, является Это? Сначала я безоговорочно скопировал его, но это нарушает мое решение. – leftaroundabout

ответ

4

Я бы поставил обработку ошибок части вне case части:

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 
+1

Я должен сказать, что с идиоматической точки зрения это очень приятное решение. Благодаря! –

10

Это хорошее приложение для 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" 
+1

Спасибо! Хорошее предложение. –