Гибкое количество аргументов для программы на Haskell
Я использую System.FilePath.Find
модуль filemanip для рекурсивного поиска всех файлов, которые мне нужно обработать (здесь я буду использовать просто печать на консоли в качестве действия для выполнения, чтобы не путать вещи). Теперь этот код:
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 тет путь1 путь2 путь4 файл1
но это конечно терпит неудачу в сопоставлении с образцом:
./myprog tet .,
myprogt: ошибка пользователя (Ошибка соответствия шаблона в выражении do в myprog.hs:11:9-22)
Теперь, как мне сделать эту программу более гибкой, чтобы я мог использовать более двух аргументов?
Извините за вопрос, на самом деле, но мои знания Haskell ограничены, но увеличиваются для каждой новой вещи, которую я должен сделать в своем первом проекте.
1 ответ
Ну, вы можете использовать другой шаблон, как:
(dbFile:inputs) <- getArgs
где dbFile
будет соответствовать первому аргументу, переданному в то время как inputs
будет соответствовать любому числу имен файлов (даже 0
, Если вы хотите использовать хотя бы одно имя пути inputs@(_:_)
вместо простого inputs
).
Тогда вы можете использовать mapM
звонить findFiles
для каждого пути в inputs
:
files <- mapM findFiles input
mapM_ putStrLn $ concat files
Вместо mapM
Вы могли бы изменить findFiles
принять [FilePath]
аргумент вместо простого FilePath
,
Обратите внимание, что для разбора аргументов команды вы можете использовать какой-то модуль, например getopt
, Вы также должны прочитать эту страницу об обработке аргументов.