Haskell 记录语法并从文件中读取。记录语法的字符串。 *** 异常:Prelude.read:没有解析
Haskell record syntax and read from file. String to record syntax. *** Exception: Prelude.read: no parse
我有以下记录语法。
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"]]
我想创建一个读取 books.txt 文件并将其转换为数据库类型的 IO 函数。我认为它需要类似于我下面的尝试。
main :: IO()
main = do fileContent <- readFile "books.txt";
let database = (read fileContent :: Database)
books.txt 文件的正确格式是什么?
以下是我当前的 books.txt 内容(与 bookDatabase 相同)。
[Book "Harry Potter" "JK Rowling" 1997 ["Sarah","Dave"]]
*** Exception: Prelude.read: no parse
记录的派生 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)
接下来,如果你看read
的类型:
> :t read
read :: Read a => String -> a
可以看到它的return类型是多态的。因此,要正确解析它,您需要让 GHC 知道您希望解析哪种类型。通常,您可以像往常一样使用解析后的值,GHC 将能够推断出类型:
getFans = do
book <- readFile "book.txt"
return $ bookFans book
但在 GHCi 中你必须给它一个提示:
> 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"]}
我有以下记录语法。
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"]]
我想创建一个读取 books.txt 文件并将其转换为数据库类型的 IO 函数。我认为它需要类似于我下面的尝试。
main :: IO()
main = do fileContent <- readFile "books.txt";
let database = (read fileContent :: Database)
books.txt 文件的正确格式是什么?
以下是我当前的 books.txt 内容(与 bookDatabase 相同)。
[Book "Harry Potter" "JK Rowling" 1997 ["Sarah","Dave"]]
*** Exception: Prelude.read: no parse
记录的派生 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)
接下来,如果你看read
的类型:
> :t read
read :: Read a => String -> a
可以看到它的return类型是多态的。因此,要正确解析它,您需要让 GHC 知道您希望解析哪种类型。通常,您可以像往常一样使用解析后的值,GHC 将能够推断出类型:
getFans = do
book <- readFile "book.txt"
return $ bookFans book
但在 GHCi 中你必须给它一个提示:
> 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"]}