Как перечислить все файлы в текущем каталоге

Я хочу написать функцию 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_' ]  

поэтому я могу применить фильтр к имени файла

Ответы

Ответ 2

Как насчет следующего:

import Data.List
import System.Directory

main = do all <- getDirectoryContents "/tmp/FOO"
          let filtered = filter (isPrefixOf "haskell") all
          print filtered

Ответ 3

Первая точка: выражение [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 ())

Ответ 4

Все, что вам нужно сделать, чтобы написать функцию, которая возвращает все файлы в текущем каталоге, следующая:

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)

Ответ 5

filemanip пакет предлагает более обобщенные и гибкие функции для этой конкретной задачи.

т.е. перечисление обычных файлов из заданного каталога

> :m + System.FilePath.Find
> :t find always (fileType ==? RegularFile)
find always (fileType ==? RegularFile) :: FilePath -> IO [FilePath]

Этот пакет совместим с Windows (поскольку он зависит от unix-compat просто unix), а также имеют аккуратные самоописательные haddocs.

Ответ 6

Здесь другой подход с использованием 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