我有这种类型我自己定义:
data Item =
Book String String String Int -- Title, Author, Year, Qty
| Movie String String String Int -- Title, Director, Year, Qty
| CD String String String Int deriving Show -- Title, Artist, Year, Qty
我创建了一个空列表
all_Items = []
使用以下功能,我试图将一个Item(Book)类型的新书插入all_Items
addBook all_Items = do
putStrLn "Enter the title of the book"
tit <- getLine
putStrLn "Enter the author of the book"
aut <- getLine
putStrLn "Enter the year this book was published"
yr <- getLine
putStrLn "Enter quantity of copies for this item in the inventory"
qty <- getLine
Book tit aut yr (read qty::Int):all_Items
return(all_Items)
但是我收到了这个错误:
Couldn't match expected type `IO a0' with actual type `[a1]'
错误指向我使用consing运算符将新书添加到列表的行。我可以认为这是一个类型错误,但我无法弄清楚我做错了什么以及如何解决它。在此先感谢!
答案 0 :(得分:3)
这一行
Book tit aut yr (read qty::Int):all_Items
获取现有列表all_Items
和新Item
值,创建新列表,其中包含新Item
值和所有项目all_Items
。 它不会修改 all_Items
。
但这不是错误信息的内容。
该行位于执行i / o的do-block中。每个语句必须是IO something
类型的表达式(可能将something
值绑定到变量)或let语句。
而这一行
Book tit aut yr (read qty::Int):all_Items
是[Item]
类型的表达式。但预计会IO something
,因此错误。
如何解决这些错误:用
替换do-block的最后两行 return (Book tit aut yr (read qty::Int):all_Items)
另请注意
你有
all_Items = []
和
addBook all_Items = do
在第一种情况下,all_Items
是顶级值。在第二种情况下,它是addBook
函数的参数。它们是不同的东西。
您已经告诉Haskell Book
构造函数的第四个参数是Int
。你不需要重复自己。所以addBook
的最后一行可以是
return (Book tit aut yr (read qty) : all_Items)