Search code examples
haskellio-monad

Any way to make a cleaner version of this Haskell IO function?


I've got this large number of IConnection conn => conn -> IO () functions that I need to execute to setup a database correctly. Now, It's not very beautiful like it is, but I am too much of a beginner in Haskell to make it better.

setup :: IConnection conn => conn -> IO ()
setup conn = do 
    setupUtterances conn
    commit conn
    setupSegments conn
    commit conn
    setupLevels conn
    commit conn
    setupLevelLevel conn
    commit conn
    setupTCLevelLevel conn
    commit conn
    setupPaths conn
    commit conn
    setupLabelTypes conn
    commit conn 
    setupLegalLabels conn
    commit conn
    setupTracks conn
    commit conn
    setupVariables conn
    commit conn 
    setupFeatures conn
    commit conn
    setupAssociations conn
    commit conn
    return ()

Anyway to shorten it? I was playing with

sequence $ map ($ conn) [func1, func2,...]

But I cannot get it to work. Suggestions?


Solution

  • Simply collect a list of the functions, map the function application and intersperse the commits. Then you just sequence your actions and manually call the final commit:

    import Data.List (intersperse)
    -- ... other things
    
    setup :: IConnection => -> IO ()
    setup conn =
        let ops = [ setupUtterances
                  , setupSegments
                  , setupLevels
                  , setupLevelLevel
                  , setupTCLevelLevel
                  , setupPaths
                  , setupLabelTypes
                  , setupLegalLabels
                  , setupTracks
                  , setupVariables
                  , setupFeatures
                  , setupAssociations
                  ]
            acts = map ($ conn) $ intersperse commit ops
        in sequence_ acts >> commit conn