Ответ 1
Кажется, что вы ищете:
getDirectoryContents :: FilePath -> IO [FilePath]
Refer: http://www.haskell.org/ghc/docs/6.12.2/html/libraries/directory-1.0.1.1/System-Directory.html#1
Я хочу написать функцию Haskell для возврата файлов текущего каталога, например.
Измените текущий каталог на
:cd c:/code/haskell
Затем напишите функцию, которая возвращает файлы в наборе, например,
[x | x <-getDirectoryContents ]
Отредактировано:
Я написал функцию sth, которая отображает файлы (ref: http://zvon.org/other/haskell/Outputdirectory/index.html)
import Directory
main = _dir "/tmp/FOO"
_dir _path =do
setCurrentDirectory _path
_cd <- getCurrentDirectory
print _cd
_file <- getDirectoryContents _cd
print _file
поэтому вызов _dir "c:/code/haskell" будет отображать все файлы + имена каталогов (нерекурсивные). Теперь я хочу назвать это в предикатной функции, например:
[ x| x <- _dir "c:/code/haskell" | x start with 'haskell_' ]
поэтому я могу применить фильтр к имени файла
Кажется, что вы ищете:
getDirectoryContents :: FilePath -> IO [FilePath]
Refer: http://www.haskell.org/ghc/docs/6.12.2/html/libraries/directory-1.0.1.1/System-Directory.html#1
Как насчет следующего:
import Data.List
import System.Directory
main = do all <- getDirectoryContents "/tmp/FOO"
let filtered = filter (isPrefixOf "haskell") all
print filtered
Первая точка: выражение [x | x <- lst]
точно такое же, как lst
, поэтому, если lst
- это список, то это использование понимания списка необязательно.
Во-вторых: для работы [x | x <-getDirectoryContents ]
значение getDirectoryContents
должно быть списком. Но это не так! getDirectoryContents
- значение IO.
Вы можете использовать эту функцию следующим образом (внутри монадического выражения):
do
files <- getDirectoryContents "."
print files
(или - внутри ghci - используйте: do; files <- getDirectoryContents "."; print files
)
(files
имеет тип [FilePath]
, а выражение while имеет тип IO ()
)
Все, что вам нужно сделать, чтобы написать функцию, которая возвращает все файлы в текущем каталоге, следующая:
import System.Directory
filesInCurDir = getCurrentDirectory >>= getDirectoryContents
Оператор → = является оператором секвенции монады с передачей значения. Это лучше всего описано здесь http://www.haskell.org/tutorial/monads.html.
Если вы собираетесь использовать это внутри ghci:
let filesInCurDir = getCurrentDirectory >>= getDirectoryContents
вы можете проверить, что функция имеет тип filesInCurDir :: IO [FilePath]
, сохраняя при этом "монадический характер".
Таким образом, если вы хотите дополнительно фильтровать файлы, которые вы можете сделать:
let filteredFilesInCurDir =
getCurrentDirectory >>=
getDirectoryContents >>=
\files -> return [ x | x <- files, (length x) > 10 ]
Если вы хотите передавать фильтр каждый раз:
let filterFilesInCurDir f =
getCurrentDirectory >>=
getDirectoryContents >>=
\files -> return [ x | x <- files, f x ]
что совпадает с:
let filteredFilesInCurDir f =
getCurrentDirectory >>=
getDirectoryContents >>=
return . filter f
и вы можете использовать его как:
filterFilesInCurDir (\x -> (length x) > 2)
filemanip
пакет предлагает
более обобщенные и гибкие функции для этой конкретной задачи.
т.е. перечисление обычных файлов из заданного каталога
> :m + System.FilePath.Find
> :t find always (fileType ==? RegularFile)
find always (fileType ==? RegularFile) :: FilePath -> IO [FilePath]
Этот пакет совместим с Windows (поскольку он зависит от unix-compat
просто unix
), а также имеют аккуратные самоописательные haddocs.
Здесь другой подход с использованием Control.Applicative
:
import Control.Applicative
import System.Directory
isRegularFileOrDirectory :: FilePath -> Bool
isRegularFileOrDirectory f = f /= "." && f /= ".."
main :: IO ()
main = do
fileNames <- filter isRegularFileOrDirectory <$> getDirectoryContents "."
putStrLn $ show $ fileNames