1

I have two record types

data OptionalRecord = OptionalRecord
  { mFoo :: Maybe Foo
  , mBar :: Maybe Bar
  , mBaz :: Maybe Baz
  }

data RequiredRecord = RequiredRecord
  { foo :: Foo
  , bar :: Bar
  , baz :: Baz
  }

I have a function:

optionalToRequired :: OptionalRecord -> Maybe RequiredRecord
optionalToRequired OptionalRecord{..} =
  do
    foo <- mFoo
    bar <- mBar
    baz <- mBaz
    return RequiredRecord{..}

This funcion works fine, but when it returns Nothing, I don't have any info about which field (or line in the do block) was Nothing. Does anyone have any suggestions for an alternative that includes more info, like line number, that doesn't require a lot of embellishment?

nick
  • 13
  • 2
  • 3
    `Either` is normally used to return an error message: https://hackage.haskell.org/package/base-4.14.0.0/docs/Prelude.html#t:Either – Willem Van Onsem Nov 10 '20 at 00:04
  • 1
    Does this answer your question? [How is it possible to collect all error messages in the Either Monad?](https://stackoverflow.com/questions/63346279/how-is-it-possible-to-collect-all-error-messages-in-the-either-monad) – Mark Seemann Nov 10 '20 at 06:29

2 Answers2

1

William's suggestion in the comments is a good one: if you use Either instead of Maybe, then instead of Nothing, your computations can produce information about why they failed. But you do have to provide this information: you can't just get it automatically from the compiler with a line number for the bind. Indeed you can't introduce any information with a bind that doesn't come from the monadic value being binded, because this would break the Monad laws.

A common example of this is "What if I could count how many calls to >>= (or uses of <- in do-notation) there have been?". You can see why that doesn't work in the question Is it possible to create a Monad that count the number of instructions?.

amalloy
  • 89,153
  • 8
  • 140
  • 205
1

As others have stated, Either a meets the requirements you've mentioned, but there is a very good reason for this: Either a behaves the same as Maybe as a Monad.

  1. It can only hold a single value or no values.
  2. An "error" value (Left foo or Nothing) short-circuits further computations whereas a "success" value (Right bar or Just bar) does not. (This means that you can only use Right as an indication of success and Left as an indication of an error.)
  3. You can pattern-match "error" and "success" values at the end.

There is a large variety of Monad semantics out there, and having the concept of an error message isn't alone sufficient to take the place of Maybe.