как вывести список всех файлов в текущем каталоге - PullRequest
14 голосов
/ 11 июля 2011

Я хочу написать функцию на Haskell для возврата файлов текущего каталога, например,

Измените текущий каталог на

 :cd c:/code/haskell

Затем напишите функцию, которая возвращает файлы вНапример:

 [x | x <-getDirectoryContents ]

Отредактировано:

Я написал такую ​​функцию, которая перечисляет файлы (ссылка: 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_' ]  

чтобы я мог применить фильтр к имени файла

Ответы [ 6 ]

20 голосов
/ 11 июля 2011

Кажется, вы ищете:

getDirectoryContents :: FilePath -> IO [FilePath]

См .: http://www.haskell.org/ghc/docs/6.12.2/html/libraries/directory-1.0.1.1/System-Directory.html#1

8 голосов
/ 11 июля 2011

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

import Data.List
import System.Directory

main = do all <- getDirectoryContents "/tmp/FOO"
          let filtered = filter (isPrefixOf "haskell") all
          print filtered
5 голосов
/ 18 июля 2014

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

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 голосов
/ 11 июля 2011

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

3 голосов
/ 08 ноября 2014

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

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

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

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

1 голос
/ 11 марта 2015

Вот еще один подход с использованием 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...