0

I am trying to extract the value in the Right constructor of a Either value, while giving an error if the Either in question is actually a Left (i.e. an error). The answers in Either Right Left how to read value gives me something like:

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

This works but discards useful information in the error message of the Left ctor of Either. How can I post an error message about the Left instead?

-- EDIT --

Thanks for the input. I wanted this as a more informational version of fromJust.

Also, I'd like to avoid writing a case statement every time, and want to avoid Monads whenever it's not too complicated (to keep the function "eval" style). For my use case, it's computation-oriented, and errors occur only when something like invalid input was supplied (when there is no remedy).

I ended up using:

fromRight e = either (error.show) id e
Community
  • 1
  • 1
thor
  • 21,418
  • 31
  • 87
  • 173
  • 3
    Why do you need this? If your code uses `fromRight` because it expects a `Right` value, then maybe it shouldn't deal with `Either` in the first place. I.e. callers of `fromRight` would have to first check whether it's `Right` value. After having seen that other question you linked to, something like `case parseCVS contents of Left error -> print error; Right data -> handle data`. – Frerich Raabe Jan 06 '16 at 00:57
  • @FrerichRaabe 1) I need this to avoid writing the `case` statement you wrote every time. I need to extract the return from another function that contains error info. The errors are rare and only happens when the input is invalid. 2) I don't want to use heavy stuff like Monads. The from here is ideal in that it's one function wrapper/one word longer. More succinct to use than the other options. – thor Jan 06 '16 at 03:59
  • The Either Monad usually helps to do computation without resorting to numerous case/if statement. Using the `fromRight` pattern inside a function makes it difficult to know that this particular function may fail and difficult to handle the failure, even it the failure rarely occurs. – zigazou Jan 06 '16 at 06:01
  • @zigazou I am aware of the `Either/Maybe` monad. The same can be said about `fromJust`. All depends on the use case. Whether you want go bullet-proof with dependent types or allow yourself occasional use of things like `head` and `fromJust` or `fromEither` here, it depends on the cost benefit ratio. – thor Jan 06 '16 at 06:16
  • As it happens, something like `head` or `fromJust` or `fromEither` not only tend to be a code smell for correctness reasons (it means you're dealing with partial functions, something which is frowned upon by many Haskellers), there's also often a much simpler way to solve the problem. Maybe it would be worthwhile to post another question where you outline why/where you need to write the `case` expression multiple times with some sample code. – Frerich Raabe Jan 06 '16 at 08:43
  • @FrerichRaabe I don't think it has much to do with `correctness reasons`. Partial functions are still correct. You get the correct answer when there is one and none when no. The solution I get from here and the linked post is simple enough. I doubt that there is `a much simpler way` and certainly don't think there is much point to post another question. Regarding the `case` expression you mention, I need to use something like fromRight in multiple occasions, each time a single call. I don't want to expand it into `case` as you suggested. Hence this question. – thor Jan 06 '16 at 16:44
  • On the other hand, if it's a string of `fromEither` or `fromJust`, I agree with you that using a Monad is probably better. – thor Jan 06 '16 at 16:45
  • @tinlyx Partial functions *do* have a lot to do with correctness since a compiler won't tell you if you are using the function incorrectly. You only notice it at runtime (and only if you have proper tests to actually exercise that condition). It's must better to express the possibility of failure via types, because then your compile will tell you if you neglected to consider that possibility. *That* is why partial functions like `head` or `fromJust` or `fromEither` are a code smell. – Frerich Raabe Jan 12 '16 at 18:34

2 Answers2

4

Instead of using const ... in the first argument of either, use something else.

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

Or whatever.


Note, however, that error should only be used for internal errors. User errors, connectivity errors, etc., should be allowed to bubble out to IO and then reported with throwIO or handled gracefully.

dfeuer
  • 48,079
  • 5
  • 63
  • 167
3

Instead of

const $ error "Left encountered"

you can use a lambda to get the value and use it, e.g.

\v -> error $ "Left encountered: " ++ v
Frerich Raabe
  • 90,689
  • 19
  • 115
  • 207