В чем разница между Either и Except в Haskell? - PullRequest
0 голосов
/ 07 ноября 2018

У меня есть класс, который может быть создан из нескольких аргументов в Haskell, который требует некоторой сложной проверки этих аргументов. В настоящее время у меня есть что-то вроде

makeAThingExcept :: String -> String -> ... String -> Except ThingError AThing
makeAThingExcept s1 s2 ... = do
    unless (s1CheckPasses s1) (throwError (BadS1 s1))
    ...

data ThingError = BadS1 String ...

instance Show ThingError where
        show (BadS1 s) = "Bad S1: " ++ s

makeAThing :: String -> String -> ... String -> AThing
makeAThing s1 s2 ... = case runExcept (makeAThingExcept s1 s2 ...) of
        Right thing  -> thing
        Left err -> error (show err)

Если оставить в стороне, есть ли лучший способ сделать это, используя более конкретные типы, чем String в качестве аргументов для makeAThingExcept, есть ли причина предпочитать Except над Either в подобном случае? Каковы различия между возможностями и идиомой Except против Either?

Ответы [ 2 ]

0 голосов
/ 30 января 2019

Разница в случае Alternative. «Базовый» пакет не экспортирует ничего для Either, как я полагаю, потому что авторы не хотели вводить смещение по отношению к какому-либо из значений, что само по себе является следствием того, что Either должна быть общей суммой. тип, а не только для представления возможных ошибок. Однако пакет «преобразователи» предоставляет экземпляр-сироту , который связывает его с классом Error :

Error e => Alternative (Either e)

Однако сообщество никогда не принимало ни этот класс типов, ни экземпляр-сироту, поэтому сейчас оно устарело. Теперь вы можете посмотреть на это так, как будто у Either еще нет экземпляра Alternative.

Тип Except имеет не-сиротский экземпляр, который даже не привязывает пользователя к каким-либо выдуманным классам, но вместо этого Monoid:

(Functor m, Monad m, Monoid e) => Alternative (ExceptT e m)
0 голосов
/ 07 ноября 2018

Как отмечается в комментариях, легко конвертировать между Except & Either. Представление во время выполнения такое же, даже.

Я бы всегда выбрал Either. Это вездесуще в библиотеках. Я очень редко вижу Except.

Except - это особый случай Кроме T , который вы увидите в библиотеках. Если вы обнаружите, что пишете множество функций с помощью Reader SomeType (Either e a) или IO (Either e a) или Monad m => m (Either e a), то вы можете рассмотреть ExceptT. Вполне нормально не беспокоиться об этом до тех пор - Either проще в использовании, пока это не так.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...