Создание временного каталога в Haskell

Каков правильный способ безопасного создания временного каталога в Haskell? System.IO предлагает способы создания временных файлов, но я не могу найти ничего, что делает то же самое для каталогов, ни там, ни в System.Directory, System.Posix.Directory, ни System.Posix.Temp. Есть ли функция, которую я пропускаю, или мне нужно написать ее самостоятельно? (И если да, есть ли опасности избежать, например, есть временные файлы?)

Ответ 1

Для работы с Unix-системами пакет Unixutils содержит такую ​​функцию:

withTemporaryDirectory:: FilePath → (FilePath → IO a) → IO a

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

withTemporaryDirectory:: FilePath → String → (FilePath → IO a) → IO a

Ответ 2

Для примера вы можете посмотреть модуль Distribution.Compat.TempFile источника Cabal. Он определяет createTempDirectory следующим образом (где c_getpid и mkPrivateDir зависят от платформы):

createTempDirectory :: FilePath -> String -> IO FilePath
createTempDirectory dir template = do
  pid <- c_getpid
  findTempName pid
  where
    findTempName x = do
      let dirpath = dir </> template ++ show x
      r <- try $ mkPrivateDir dirpath
      case r of
        Right _ -> return dirpath
        Left  e | isAlreadyExistsError e -> findTempName (x+1)
                | otherwise              -> ioError e

Тот факт, что Cabal определяет эту функцию, предполагает, что нет стандартного способа сделать это.

Ответ 3

Как предложил @Никита Волков, я оставляю комментарий @Thomas M. DuBuisson как отдельный ответ:

Используйте пакет temporary. Он обеспечивает удобный независимый от платформы API для использования временных файлов и каталогов. Временные файлы и каталоги автоматически удаляются после использования.