Reputation: 39
I have some code like this:
data Set = Set String [Int]
deriving (Show, Read)
getArr :: Set -> [Int]
getArr (Set _ arr) = arr
My goal is to write a function that will input a list of values into a tuple.
EG:
data --
"One" [1], "Two" [2], "Three" [3]
output: "One" [0, 1], "Two" [1,2], "Three" [3,3]
with the input being [0, 1, 3]
My general aproach to this was to go recursively over the data going one by one and at the same time going over the list of values one by one using : to add it onto the first index.
I attempted to do something like:
addToSet :: [Set] -> [Int] -> [Set]
addToSet [] [] = []
addToSet (x:xs) (y:ys) = (getArr x : y) ++ addToSet xs
but i get an error saying :
Couldn't match type ‘[Int]’ with ‘Set’
Expected type: [Set]
Actual type: [[Int]]```
Upvotes: 1
Views: 62
Reputation: 532368
Consider the helper function
updateSet :: Set -> Int -> Set
updateSet (Set s xs) y = Set s (y:xs)
This simply adds a single value to a given set:
>>> updateSet (Set "One" [1]) 0
Set "One" [0,1]
Then addToSet
is just a wrapper around zipWith
:
addToSet :: [Set] -> [Int] -> [Set]
addToSet = zipWith updateSet
updateSet
is called on the first set and the first integer, then the second set and the second integer, and so on, with the results combined in order in a single list.
Another way to think of this is mapping a function of type (Set, Int) -> Int
over the result of zipping the two lists together:
updateSet' :: (Set, Int) -> Set
updateSet' (Set s xs, y) -> Set s (y:xs)
addToSet :: [Set] -> [Int] -> [Set]
addToSet ss is = map updateSet' (zip ss is)
Note that updateSet' = uncurry updateSet
.
Upvotes: 1