Search code examples
haskellmonads

How do I apply a series of monadic actions to the same argument in Haskell?


In Haskell, is there a way to simplify the following code to remove the repeating of "hello world"? In other words, applying f, g, and h to hello world?

fn = do
  a <- f "hello world"
  b <- g "hello world"
  c <- h "hello world"
  return (a, b, c)

Solution

  • If f, g and h have the same type, you can simply loop over them:

      [a,b,c] <- forM [f,g,h] ($"hello world")
    

    If they have different types, you can use the fact that functions form a monad, and in particular can be stacked as a monad transformer on top of your current monad:

    import Control.Monad.Trans.Reader
    
    fn = (`runReaderT`"hello world") $ do
        a <- ReaderT f
        b <- ReaderT g
        c <- ReaderT h
        return (a, b, c)