Ошибка чтения и записи одного и того же файла одновременно в Haskell

Мне нужно изменить файл на месте. Поэтому я планировал прочитать содержимое файла, обработать его, а затем записать вывод в тот же файл:

main = do
  input <- readFile "file.txt"
  let output = (map toUpper input) 
  -- putStrLn $ show $ length output
  writeFile "file.txt" output

Но проблема в том, что он работает, как и ожидалось, только если я раскомментирую 4-ю строку - где я просто выводю количество символов на консоль. Если я не раскомментирую это, я получаю

openFile: resource busy (file is locked)

Есть ли способ заставить чтение этого файла?

1 ответ

Решение

Самая простая вещь может быть строгой ByteString IO:

import qualified Data.ByteString.Char8 as B

main = do
  input <- B.readFile "file.txt"
  B.writeFile "file.txt" $ B.map toUpper input

Как видите, это тот же код, но некоторые функции заменены на ByteString версии.

Ленивый И.О.

Проблема, с которой вы сталкиваетесь, заключается в том, что некоторые функции ввода-вывода в Haskell используют "Lazy IO", который имеет удивительную семантику. Почти в каждой программе я бы избегал ленивых операций ввода-вывода.

В наши дни люди ищут замены для ленивых операций ввода-вывода, таких как Conduit и тому подобное, и ленивые операции ввода-вывода воспринимаются как отвратительный хак, который, к сожалению, застрял в стандартной библиотеке.

Другие вопросы по тегам