Search code examples
haskellhaskell-lens

How to override a default value, via lenses, only if incoming value is not Nothing


I'm basically trying to override a bunch of default values in a record only if the user-specific values are NOT Nothing. Is it possible to do it via lenses?

import qualified Data.Default as DD

instance DD.Def Nouns where
  def  = Nouns
    {
      -- default values for each field come here
    }

lookupHStore :: HStoreList -> Text -> Maybe Text

mkNounsFromHStoreList :: HStoreList -> Nouns
mkNounsFromHStoreList h = (DD.def Nouns)
  & depSingular .~ (lookupHStore h "dep_label_singular")
  -- ERROR: Won't compile because Text and (Maybe Text) don't match

Solution

  • You could make your own combinator:

    (~?) :: ASetter' s a -> Maybe a -> s -> s
    s ~? Just a  = s .~ a
    s ~? Nothing = id
    

    Which you can use just like .~:

    mkNounsFromHStoreList :: HStoreList -> Nouns
    mkNounsFromHStoreList h =
      DD.def
        & myNoun1 ~? lookupHStore h "potato"
        & myNoun2 ~? lookupHStore h "cheese"