2016-11-04 8 views
1

Возможно ли скопировать сообщения об ошибках в Monad ErrorT? Я хотел бы накопить больше одной ошибки.Накопление ошибок с использованием ErrorT

+0

'Either' /' ExceptT'/'ErrorT' по своей сути предназначены для короткого замыкания, поэтому ответ« нет ». Если вы хотите скопировать несколько ошибок, вы должны использовать другой трансформатор monad/monad, в данном случае, вероятно, 'WriterT'. –

+0

Трудно ли заменить ErrorT на WriterT? В этот момент у меня есть «башня: из монады (StateT, ErrorT, IO) –

+2

Это не сложно в том смысле, что это механически сложно, но это может быть сложно в том смысле, что' ErrorT' и 'WriterT' имеют чрезвычайно разную семантику. Весь смысл «ErrorT» заключается в том, что он позволяет с ошибками вычислять. Если вы хотите скопировать более одной ошибки, значит, вы, вероятно, хотите, чтобы вычисления продолжали идти. Подумайте, какие последствия для вашего кода - можете ли вы действительно продолжать идти после сбоя? Если ответ «иногда», вам может понадобиться смесь 'WriterT' и' ExceptT' ('ErrorT' устарел, кстати, вместо этого используйте' ExceptT'). –

ответ

4

Вы можете использовать Errors Аппликативные из Control.Applicative.Liftиз трансформаторов:

ghci> import Control.Applicative 
ghci> import Control.Applicative.Lift 
ghci> failure ['a'] *> pure() <* failure ['b'] 
Other (Constant "ab") 

возвращает список ошибок, если таковые имеются, или успешный результат.

Этот тип обычно известен как «Валидация». Есть other implementations из имеющихся в Hackage. Одно из возможных улучшений заключается в том, чтобы уменьшить потребность в контейнере отказов Monoid, что позволяет также Semigroup с.

Обратите внимание, что тип Errors не является Monad. Но вы можете комбинировать его с другими Applicative с помощью Data.Functor.Compose.


MonadPlus экземпляра для ExceptT имеет связанное, но не идентичное поведение: он возвращает первый успех, если есть, или список ошибок:

ghci> throwE ['a'] `mplus` return() `mplus` throwE ['b'] :: ExceptT [Char] Identity() 
ExceptT (Identity (Right())) 
ghci> throwE ['a'] `mplus` throwE ['b'] :: ExceptT [Char] Identity() 
ExceptT (Identity (Left "ab")) 

 Смежные вопросы

  • Нет связанных вопросов^_^