在Haskell中使用用户定义的类型构建列表

时间:2012-04-07 23:12:45

标签: list haskell types user-defined-types

我有这种类型我自己定义:

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运算符将新书添加到列表的行。我可以认为这是一个类型错误,但我无法弄清楚我做错了什么以及如何解决它。在此先感谢!

1 个答案:

答案 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)