Reputation: 563
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
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
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