使用mapM f [list],其中f用do表示法定义

时间:2013-02-19 07:06:49

标签: haskell

我目前拥有此代码,该代码将对列表main'中的每个文件名执行files功能。

理想情况下,我一直在尝试合并mainmain',但我没有取得多大进展。有没有更好的方法来简化这一点,还是我需要将它们分开?

{- Start here -}
main :: IO [()]
main = do
    files <- getArgs
    mapM main' files

{- Main's helper function -}
main' :: FilePath -> IO ()
main' file = do 
    contents <- readFile file
    case (runParser parser 0 file $ lexer contents) of Left err -> print err
                                                       Right xs -> putStr xs

谢谢!

编辑:正如大多数人所建议的那样;我为此尝试了一个lambda抽象,但是没有把它弄好。 - 应该在上面说明了这一点。通过这些例子,我看得更清楚。

2 个答案:

答案 0 :(得分:6)

Control.Monad库定义函数forMmapM是反向参数。这使得在您的情况下更容易使用,即

main :: IO ()
main = do
    files <- getArgs
    forM_ files $ \file -> do
        contents <- readFile file
        case (runParser f 0 file $ lexer contents) of
            Left err -> print err   
            Right xs -> putStr xs

如果您对结果列表不感兴趣,则使用名称末尾带有下划线的版本(如本例所示),因此main可以只使用类型IO ()。 (mapM有一个名为mapM_)的类似变体。

答案 1 :(得分:5)

您可以使用等于forM的{​​{1}},即flip mapM及其参数翻转,如下所示:

mapM

另请注意,我使用forM_ files $ \file -> do contents <- readFile file ... 代替forM_。当您对计算结果不感兴趣时​​,这会更有效。