functionalCode
functionalCode

Reputation: 563

Haskell data type dilemma

Hey everyone I am working on a piece of Haskell code and cannot figure out how to fix this problem.

I get this error:

Couldn't match expected type `Collection' with actual type `[a0]'
In the expression: [list] ++ numberToInsert
In an equation for `insert':
    insert numberToInsert (Set [list])
      | contains (Set [list]) numberToInsert == True = (Set [list])
      | otherwise = [list] ++ numberToInsert

Failed, modules loaded: none.

Here is my code

data Collection = Set [Int] deriving (Show)


insert :: Int -> Collection -> Collection
insert numberToInsert (Set [list])
    |contains (Set [list]) numberToInsert == True = (Set [list])
    |otherwise = [list] ++ numberToInsert  <--- this is my problem

contains :: Collection -> Int -> Bool
contains (Set []) numberToFind = False
contains (Set (x:xs)) numberToFind
    |x == numberToFind = True
    |otherwise = contains (Set (xs)) numberToFind

Can someone help me fix this?

Thanks

Upvotes: 0

Views: 205

Answers (2)

Adam Wagner
Adam Wagner

Reputation: 16117

It appears you have two issues with your insert function.

First, your two definitions of the insert function return different things.

Set [list]   -- Return type here is Collection

and

[list] ++ numberToInsert  -- Return type here is some sort of list, or [a0]

So first, you'll need to Make the second version return a Collection:

Set ([list] ++ numberToInsert)

But this is still wrong, because numberToInsert is not a list, and ++ concatenates two lists together, so I think you're really wanting to push it onto the front of your [list]. : is used to push some a onto the front of a list of as Like so:

Set (numberToInsert:[list])

Finished product:

insert :: Int -> Collection -> Collection
insert numberToInsert (Set [list])
    | contains (Set [list]) numberToInsert == True = (Set [list])
    | otherwise = Set (numberToInsert : [list])

Update

As you mentioned, there is one other issue I'd missed. list shouldn't be wrapped in the square brackets, and here's why (in case you hadn't figured it out).

When you use the square brackets in a pattern match (the left side of the =), you're saying: "give me a list that looks like this, and bind it's only item to some name for use later". So you were only expecting a list with one item, and decided to call that item list.

Next, you repackaged up that one item in the new list when you used it as [list].

this example:

foo [a] = a
main = print $ foo [1]

would print '1'. Passing a list of two items, however, would fail to pattern match, because you had no foo [a, b] = ... function defined, hence the warning:

main = print $ foo [1, 2]

So yes, removing all of the square brackets works because you are not requiring the list have only one item, but instead saying "the entire list will be called list", which is probably what you wanted in the first place.

Upvotes: 2

Nathan Howell
Nathan Howell

Reputation: 4637

Here ya go.

import Data.List (elem)

data Collection = Set [Int] deriving (Show)

insert :: Int -> Collection -> Collection
insert numberToInsert c@(Set list)
  | numberToInsert `elem` list = c
  | otherwise = Set (numberToInsert:list)

Upvotes: 1

Related Questions