import Data.Foldable (toList, foldlM) foldrM :: (Foldable t, Monad m) => (a -> b -> m b) -> b -> t a -> m b foldrM f z = foldlM (flip f) z . lazyReverse . toList lazyReverse :: [a] -> [a] lazyReverse l = go l (reverse l) where go [] _ = [] go (_ : xs) ~(y : ys) = y : go xs ys main :: IO () main = do let u = undefined print @(Maybe Int) $ foldrM (\_ _ -> Nothing) 0 [] print @(Maybe Int) $ foldrM (\_ _ -> Nothing) u (u : u) print @(Either Int Int) $ foldrM (\_ z -> Left z) 0 (u : u) print @(Either Int Int) $ foldrM (\_ z -> Right z) 0 [u, u] print @(Either Int Int) $ foldrM (\i _ -> Left i) u [u, 2] print @(Either Int Int) $ foldrM (\i _ -> Right i) u [1, u]