Search code examples
haskellhaskell-lens

Getting Maybe from lens with default value


A lot of lens getters return Maybe values. And i often need to replace them with some default.

Say map lookup but with default.

fromMaybe "" $ Map.fromList [(1,"Foo")] ^? at 1

Can this be written with lens syntax? Maybe something close to this:

Map.fromList [(1,"Foo")] ^? at 1.or ""

Solution

  • I think what you want is

    non :: Eq a => a -> Iso a (Maybe a)
    

    non foo essentially does

     case someMaybe of
       Nothing -> foo
       Just a  -> a
    

    In your case

     someMap ^. at 1 . non ""
    

    Coincidentally, this is precisely the example of non the docs give.

    If you want to use this with ix you're out of luck, but you can always do

     -- Import Data.Monoid
     defaulting :: a -> s -> Getting (First a) s a -> a
     defaulting a s fold = fromMaybe a $ s ^? fold
    
     foo = defaulting 0 [1, 2, 3] $ ix 3 -- 0