¿Cómo leo (y analizo) un archivo y luego lo anexo al mismo sin obtener una excepción?

Estoy tratando de leer un archivo correctamente en Haskell pero parece que aparece este error.

*** Excepción: neo.txt: openFile: recurso ocupado (el archivo está bloqueado) Este es mi código.

import Data.Char
import Prelude
import Data.List
import Text.Printf
import Data.Tuple
import Data.Ord
import Control.Monad
import Control.Applicative((<*))

import Text.Parsec
    ( Parsec, ParseError, parse        -- Types and parser
    , between, noneOf, sepBy, many1    -- Combinators
    , char, spaces, digit, newline     -- Simple parsers
    )

Estos son los campos de la película.

type Title = String
type Director = String
type Year = Int
type UserRatings = (String,Int) 
type Film = (Title, Director, Year , [UserRatings])
type Period = (Year, Year)
type Database = [Film]

Este es el análisis de todos los tipos para leer correctamente desde el archivo

-- Parse a string to a string
stringLit :: Parsec String u String
stringLit = between (char '"') (char '"') $ many1 $ noneOf "\"\n"

-- Parse a string to a list of strings
listOfStrings :: Parsec String u [String]
listOfStrings = stringLit `sepBy` (char ',' >> spaces)

-- Parse a string to an int
intLit :: Parsec String u Int
intLit = fmap read $ many1 digit
-- Or `read <
-- Parse a string to a string
stringLit :: Parsec String u String
stringLit = between (char '"') (char '"') $ many1 $ noneOf "\"\n"

-- Parse a string to a list of strings
listOfStrings :: Parsec String u [String]
listOfStrings = stringLit `sepBy` (char ',' >> spaces)

-- Parse a string to an int
intLit :: Parsec String u Int
intLit = fmap read $ many1 digit
-- Or `read <$> many1 digit` with Control.Applicative
stringIntTuple :: Parsec  String u (String  , Int)
stringIntTuple = liftM2 (,) stringLit intLit

film :: Parsec String u Film
film = do
    -- alternatively `title <- stringLit <* newline` with Control.Applicative
    title <- stringLit
    newline
    director <- stringLit
    newline
    year <- intLit
    newline
    userRatings <- stringIntTuple
    newline
    return (title, director, year, [userRatings])

films :: Parsec String u [Film]
films = film `sepBy` newline
gt; many1 digit` with Control.Applicative stringIntTuple :: Parsec String u (String , Int) stringIntTuple = liftM2 (,) stringLit intLit film :: Parsec String u Film film = do -- alternatively `title <- stringLit <* newline` with Control.Applicative title <- stringLit newline director <- stringLit newline year <- intLit newline userRatings <- stringIntTuple newline return (title, director, year, [userRatings]) films :: Parsec String u [Film] films = film `sepBy` newline

Este es el programa principal (escriba "main" en winghci para iniciar el programa)

-- The Main
main :: IO ()
main = do
    putStr "Enter your Username:  "
    name <- getLine
    filmsDatabase <- loadFile "neo.txt"
    appendFile "neo.txt" (show filmsDatabase)
    putStrLn "Your changes to the database have been successfully saved."

Esta es la función loadFile

loadFile :: FilePath -> IO (Either ParseError [Film])
loadFile filename = do
database <- readFile filename 
return $ parse films "Films" database

el otro nombre de archivo txt es neo e incluye algunas películas como esta

"Blade Runner"
"Ridley Scott"
1982
("Amy",5), ("Bill",8), ("Ian",7), ("Kevin",9), ("Emma",4), ("Sam",7), ("Megan",4)

"The Fly"
"David Cronenberg"
1986
("Megan",4), ("Fred",7), ("Chris",5), ("Ian",0), ("Amy",6)

Simplemente copie y pegue todo, incluya un archivo txt en el mismo directorio y pruébelo para ver el error que describí.

Respuestas a la pregunta(2)

Su respuesta a la pregunta