--------------------------------------------------------------- -- Propagate Maybe to the top -- 980409 Patrik Jansson -- (Can be generalised to thread any monad, see Thread) --------------------------------------------------------------- module Propagate(propagate,fprop,sumprop,prodprop,mapMaybe) where import Base(cata,inn,pmap) propagate :: Regular d => d (Maybe a) -> Maybe (d a) propagate = cata (mapMaybe inn . fprop) -- Bifunctor f => ... polytypic fprop :: f (Maybe a) (Maybe b) -> Maybe (f a b) = case f of g + h -> sumprop . (fprop -+- fprop) g * h -> prodprop . (fprop -*- fprop) Empty -> Just Par -> id Rec -> id d @ g -> propagate . (pmap fprop) Const t -> Just sumprop :: Either (Maybe a) (Maybe b) -> Maybe (Either a b) sumprop = mapMaybe Left `either` mapMaybe Right prodprop :: (Maybe a,Maybe b) -> Maybe (a,b) prodprop p = case p of (Just x,Just y) -> Just (x,y) _ -> Nothing --------------------------------------------------------------- -- Maybe functions mapMaybe :: (a->b) -> Maybe a -> Maybe b mapMaybe f = maybe Nothing (Just.f)