user1319603
user1319603

Reputation: 765

Consing lists with user-defined type in Haskell

I have this type I defined myself:

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

I've created an empty list

all_Items = []

With the following function I am trying to insert a new book of type Item (Book) into the 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)

I however am receiving this error:

Couldn't match expected type `IO a0' with actual type `[a1]'

The error points to the line where I am using the consing operator to add the new book to the list. I can gather that it is a type error but I can't figure out what it is that I am doing wrong and how to fix it. Thanks in Advance!

Upvotes: 0

Views: 599

Answers (1)

dave4420
dave4420

Reputation: 47072

This line

    Book tit aut yr (read qty::Int):all_Items

takes your existing list all_Items, and a new Item value, and makes a new list consisting of the new Item value and all the items in all_Items. It does not modify all_Items.

But that's not what the error message is about.

The line is in a do-block that does i/o. Each statement must be either an expression of type IO something (possibly binding the something value to a variable), or a let statement.

Whereas this line

    Book tit aut yr (read qty::Int):all_Items

is an expression of type [Item]. But an IO something was expected, hence the error.

How to fix these errors: replace the last two lines of the do-block with

    return (Book tit aut yr (read qty::Int):all_Items)

Also note

  • You have

    all_Items = []
    

    and

    addBook all_Items = do
    

    In the first case all_Items is a top level value. In the second case it is the parameter to the addBook function. They are different things.

  • You already told Haskell that the fourth argument to the Book constructor is an Int. You don't need to repeat yourself. So the last line of addBook can be

        return (Book tit aut yr (read qty) : all_Items)
    

Upvotes: 3

Related Questions