Exception Haskell记录语法并从文件中读取。记录语法的字符串。***例外:Prelude.read:无解析

Exception Haskell记录语法并从文件中读取。记录语法的字符串。***例外:Prelude.read:无解析,exception,haskell,syntax,record,Exception,Haskell,Syntax,Record,我有下面的记录语法 type Title = String type Author = String type Year = Int type Fan = String data Book = Book { bookTitle :: Title , bookAuthor:: Author , bookYear :: Year , bookFans :: [Fan]

我有下面的记录语法

type Title = String
type Author = String
type Year = Int
type Fan = String


data Book = Book { bookTitle :: Title
                 , bookAuthor:: Author
                 , bookYear  :: Year
                 , bookFans  :: [Fan]
                 }
                 deriving (Show, Read)


type Database = [Book]

bookDatabase :: Database 
bookDatabase = [Book "Harry Potter" "JK Rowling" 1997 ["Sarah","Dave"]]
我想创建一个IO函数,读取books.txt文件并将其转换为数据库类型。我认为它需要类似于我下面的尝试

main :: IO()
main = do fileContent <- readFile "books.txt";
          let database = (read fileContent :: Database)
***例外:Prelude.read:无解析


记录的派生
Read
实例只能读取记录语法。它无法按顺序读取应用于参数的构造函数格式的记录。尝试将以下内容(这是
show bookDatabase
的结果)放入
books.txt

[Book {bookTitle = "Harry Potter", bookAuthor = "JK Rowling", bookYear = 1997, bookFans = ["Sarah","Dave"]}]

在您的示例中,有几件事需要解决

首先,在数据类型声明中,需要派生一个
Read
实例

data Book = Book {
      bookTitle :: String
    , bookAuthor :: String
    , bookYear   :: Int
    , bookFans   :: [String]
    } deriving (Show,Read)
接下来,如果您查看
的类型,请阅读

> :t read
read :: Read a => String -> a
您可以看到它的返回类型是多态的。因此,要正确解析它,您需要让GHC知道您希望解析的类型。通常,您可以像通常一样使用解析后的值,GHC将能够推断出类型:

getFans = do
    book <- readFile "book.txt"
    return $ bookFans book

问题已经在使用类型签名,
(read fileContent::Database)
,告诉编译器应该使用
[Book]
@Cirdec的
read
实例哦,当然可以。我错过了。不过,我不知道为什么会有这样的否决票。我的回答没有错,是吗?如果是的话,我很高兴知道我的错误你的答案完全正确,只是没有回答问题。作者已经有一个
Read
实例用于
Book
,或者无法编译和运行
(Read fileContent::Database)
以获取运行时错误
Prelude。Read:no parse
。您在答案末尾添加的小型ghci会话演示了
show
的功能以及
阅读。show
可以是
Book
s的标识,但不能解释为什么
books.txt
不能被阅读。@Cirdec好吧,当我写答案时,他们没有
read
实例。这个问题是事后编辑的。我承认错误地指出,
read
需要一些类型信息来操作。我可能很快就认为OP是一个初学者,这种行为会让他们感到困惑。我还认为演示<代码>阅读。show=id
表示
read
期望的格式(即show生成的格式)。
getFans = do
    book <- readFile "book.txt"
    return $ bookFans book
> let book = Book "the sound and the fury" "faulkner" 1929 ["me"] 
> show book
"Book {bookTitle = \"the sound and the fury\", bookAuthor = \"faulkner\", bookYear = 1929, bookFans = [\"me\"]}"
> read $ show book :: Book
Book {bookTitle = "the sound and the fury", bookAuthor = "faulkner", bookYear = 1929, bookFans = ["me"]}