haskell程序的灵活参数数量

时间:2014-09-19 09:12:57

标签: haskell pattern-matching command-line-arguments io-monad

我正在使用filemanip的System.FilePath.Find模块递归查找我需要处理的所有文件(这里我将仅使用打印到控制台作为要执行的操作,以免混淆事物)。现在,这段代码:

import System.Environment (getArgs)
import System.FilePath (FilePath)
import System.Directory (doesDirectoryExist, getDirectoryContents,doesFileExist)
import Control.Monad
import System.FilePath.Find (find,always,fileType,(==?),FileType(..),(&&?),extension)


main= do 
    [dbFile,input]<- getArgs
    files <- findFiles input
    mapM_ putStrLn files 
    return ()

searchExtension :: String
searchExtension = ".hs"

findFiles :: FilePath -> IO [String]
findFiles = find (always) ( fileType ==? RegularFile &&? extension ==? searchExtension)

适用于此次通话

  

./ myprog tet。

在这种情况下,忽略get参数(稍后将是输出数据库文件),并且为匹配文件递归搜索第二个参数。它还允许我只指定一个文件,这是完美的!

但是,我希望能够指定

  

./ myprog tet path1 path2 path4 file1

但当然这在模式匹配中失败了:

  

./ myprog tet。

     

myprogt:用户错误(myprog.hs中的do表达式中的模式匹配失败:11:9-22)

现在,我如何使这个程序更灵活,以便我可以使用两个以上的参数?

很抱歉,问这个,实际上,但我的Haskell知识是有限的,但我在第一个项目中必须做的每件新事情都在增加。

1 个答案:

答案 0 :(得分:5)

嗯,你可以使用不同的模式,如:

(dbFile:inputs) <- getArgs

其中dbFile将匹配传递的第一个参数,而inputs将匹配任意数量的文件名(即使0。如果您希望至少有一个路径名使用inputs@(_:_)而不是简单的inputs)。

然后,您可以使用mapMfindFiles中的每条路径致电inputs

files <- mapM findFiles input
mapM_ putStrLn $ concat files

您可以修改mapM来接受findFiles参数而不是简单的[FilePath],而不是FilePath


请注意,要解析命令参数,您可以考虑使用某些模块,如getopt。您还应阅读有关参数处理的this页面。