Retrieving values from a chain of ADT's with Maybe's

haskell, option-type

Solution

I'd write that, in the most generic case, something like:

projNameStr :: T24Report -> String
projName t24 = fromMaybe "" $ do
    title <- projTitle $ project t24
    zip title

The key point is using a `do` block to factor out handling all of the `Nothing` cases.

However, in this specific case, since there are only the two `Maybe`s in the chain, I'd be tempted to shorten it a bit:

projNameStr :: T24Report -> String
projName t24 = fromMaybe "" $ projTitle (project t24) >>= zip

That's exactly what the previous example is converted to during compilation. Usually that sort of manual desugaring makes things worse, not better. But in this case, I would be tempted to go with this, just because it's a couple lines shorter and not too much more work to read.

Problem

I have some ADT's each of which may or not contain another ADT. I need to retrieve data from lower levels and I'm writing some very repetitive code which I am sure can be eliminated. I've looked at some example code in Real World Haskell and in "Learn You a Haskell For Great Good" but I can't quite figure it out. Here is an example with irrelevent details of the ADT's left out. ``` T24Report - projTitle :: Maybe ProjectTitle - zip :: Maybe String ``` To retrieve the zip code from StreetAddress I've been ending up with this: ``` projNameStr :: T24Report -> String projNameStr t24 = if isNothing projTitleMaybe then "" else (fromMaybe "") $ zip $ fromJust projTitleMaybe where projTitleMaybe = projTitle $ project t24 ``` As the depth of the chain of objects increases, the repetitiveness of the code does too. There must be a better way. Ideas? References? I couldn't find a similar question on StackOverflow, but I believe it must be here...this seems like an simple problem that must have been asked. Thanks, Tim

Original source