3

データベースを正しくセットアップするために実行する必要がある、この多数の IConnection conn => conn -> IO () 関数があります。今、それはそれほど美しくはありませんが、私はHaskellの初心者であり、より良くすることはできません.

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 ()

とにかく短くする?と遊んでいました

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

しかし、私はそれを機能させることができません。提案?

4

3 に答える 3

0

今日はコードゴルフをしたい気分です。ワンライナー(まあ、それは1つのように始まりました):

import Control.Monad.Trans.Reader

-- | Run a sequence of actions with the same connection, committing that 
-- connection after each action.
runSetup :: IConnection conn => [conn -> IO ()] -> conn -> IO ()
runSetup = runReaderT . mapM_ withCommit
    where withCommit action = ReaderT action >> ReaderT commit

setup = runSetup actions 
    where actions = [ setupUtterances
                    , setupSegments
                    , setupLevels
                    , setupLevelLevel
                    , setupTCLevelLevel
                    , setupPaths
                    , setupLabelTypes
                    , setupLegalLabels
                    , setupTracks
                    , setupVariables
                    , setupFeatures
                    , setupAssociations
                    ]

ここでの核となる考え方は、 a が「欠けている」: anConnection -> IO ()と同じです。 、、および友人を関数としてではなく、共通の暗黙的な を共有するアクションとして扱うことができます。 は単なるモナドなので、各アクションの後に簡単に追加できます。ReaderT Connection IO ()IO ()ConnectionReaderTcommitsetupUtterancessetupSegmentsConnectionReaderT Connection IOcommit

于 2014-08-06T02:07:36.080 に答える