2016-01-06 1 views
0

Я пытаюсь извлечь значение в конструкторе Right значения Either, выдавая ошибку, если вопрос Either на самом деле является Left (т. Е. Ошибка). Ответы в Either Right Left how to read value дает мне что-то вроде:Как извлечь правую личку и сохранить информацию о ее левых в случае ошибки в Haskell?

fromRight e = either (const $ error "Either Left encountered while expecting Right") id e 

Это работает, но отбрасывает полезную информацию в сообщении об ошибке в Left CTOR из Either. Как я могу опубликовать сообщение об ошибке Left?

- EDIT -

Спасибо за ввод. Я хотел, чтобы это было более информативной версией fromJust.

Кроме того, я хотел бы избежать написания заявления case каждый раз и хочу избегать Monads, когда это не слишком сложно (чтобы сохранить функцию «eval»). Для моего варианта использования он ориентирован на вычисления, и ошибки возникают только тогда, когда поставляются какие-то недопустимые данные (когда нет средств защиты).

Я закончил с использованием:

fromRight e = either (error.show) id e 
+3

Зачем вам это нужно? Если ваш код использует 'fromRight', потому что он ожидает значение« Right », возможно, он не должен иметь дело с« Либо »в первую очередь. То есть абонентам 'fromRight' придется сначала проверить, является ли это значением' Right'. После просмотра этого другого вопроса, с которым вы связались, что-то вроде 'case parseCVS-содержимого ошибки Left error -> print error; Правые данные -> обрабатывать данные'. –

+0

@FrerichRaabe 1) Мне нужно это, чтобы избежать написания инструкции 'case', которую вы написали каждый раз. Мне нужно извлечь возврат из другой функции, содержащей информацию об ошибке. Ошибки редки и происходят только при неправильном вводе. 2) Я не хочу использовать тяжелые вещи, такие как Монады. Отсюда идеальна то, что это одна функциональная оболочка/одно слово дольше. Более сжатые в использовании, чем другие варианты. – tinlyx

+0

Либо Монада обычно помогает делать вычисления, не прибегая к многочисленным утверждениям case/if. Использование шаблона 'fromRight' внутри функции затрудняет понимание того, что эта конкретная функция может выйти из строя и не справиться с ней, даже если она редко возникает. – zigazou

ответ

5

Вместо использования const ... в первом аргументе either, использовать что-то другое.

either oops .... where 
    oops x = error $ "Oops! Got an " ++ show x 

Или что-то еще.


Однако следует отметить, что error следует использовать только для внутренних ошибок. Ошибки пользователя, ошибки подключения и т. Д. Должны быть разрешены до IO, а затем сообщаться с throwIO или обрабатываться изящно.

4

Вместо

const $ error "Left encountered" 

вы можете использовать лямбда, чтобы получить значение и использовать его, например,

\v -> error $ "Left encountered: " ++ v 
Смежные вопросы