我有大量的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,...]
但我无法让它发挥作用。建议?
答案 0 :(得分:8)
如何
setup conn = mapM_ ($ conn) $ intersperse commit
[ setupUtterances,
, setupSegments
, setupLevels
, setupLevelLevel
, setupTCLevelLevel
, setupPaths
, setupLabelTypes
, setupLegalLabels
, setupTracks
, setupVariables
, setupFeatures
, setupAssociations
, \_ -> return ()]
intersperse
在所有操作之间加上commit
,并mapM_ ($conn)
向所有conn
行动提供IO
。最后的\_ -> return ()
是为了确保在所有内容的最后调用commit
。
答案 1 :(得分:4)
只需收集函数列表,映射函数应用程序并散布提交。然后,您只需对操作进行排序并手动调用最终提交:
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
答案 2 :(得分:0)
我觉得今天要打高尔夫球。单线(嗯,它开始像一个):
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
]
这里的核心思想是Connection -> IO ()
与ReaderT Connection IO ()
相同:IO ()
“缺少”Connection
。 ReaderT
允许您将commit
,setupUtterances
,setupSegments
和朋友视为功能,而将其视为共享共同隐含Connection
的操作。 ReaderT Connection IO
只是一个monad,因此您可以轻松地在每个操作后点击commit
。