Reputation: 1
I have a list of tuples
type Sales = (String, String, Integer)
testData :: [Sales]
testData = [("Jack", "Hill", 2), ("Susan", "Smith", 5), ("Steve", "Johnson", 6)
How can I write a function that would search through the list of tuples given the first and last names and output the number, and let me edit that number?
I'm trying to have something like:
recordSale "Jack" "Hill" -- and the function return 2
And another which would do:
addSale "Jack" "Hill" -- and it would add 1 to the database corresponding to the name
So far I've tried
recordSale tData Fname Lname= find (\(Fname, Lname, _) tData
recordSale tData Fname Lname = [(Fname, Lname, map (\tData -> tData + 1) sales) | (Fname, Lname, sales) <- tData]
nothing seems to work though, and most help I find only works with tuples with 2 elements, not 3.
Upvotes: 0
Views: 190
Reputation: 20843
It might be worthwhile to use a Data.Map
. If you want to stick with tuples you can break it into smaller step.
Write a function that given a Sale
returns the sale count.
saleCount :: Sale -> Integer
saleCount (first, last, count) = undefined -- to do
Write a function that given a name, checks if the passed tuple matches. (This is commonly called a predicate and will help you in the next step.)
isMatching :: String -> String -> Sale -> Bool
isMatching first last (saleFirst, saleLast, saleCount) = undefined -- to do
Use find @[] :: (a -> Bool) -> [a] -> Maybe a
. While trying with find the question will arise what you want to happen, if the list does not contain or tuple or multiple tuples.
For updating the list you can have a look at Replace individual list elements in Haskell?
Upvotes: 1
Reputation: 1732
As a side note, the example testData is missing the closing square bracket.
A function to search the testData is shown below.
type Sales = (String, String, Integer)
testData :: [Sales]
testData = [("Jack", "Hill", 2), ("Susan", "Smith", 5), ("Steve", "Johnson", 6)]
findNumber:: [Sales] -> String -> String -> Integer
findNumber (x:xs) name1 name2 =
findNumberIter (x:xs) name1 name2 (-1)
where
findNumberIter [] _ _ number = number
findNumberIter (x:xs) name1 name2 number =
if xname1 == name1 && xname2 == name2 then
findNumberIter xs name1 name2 xnumber
else
findNumberIter xs name1 name2 number
where
(xname1,xname2,xnumber) = x
main = putStrLn $ show $findNumber testData "Jack" "Hill"
We run a tail recursion, going through the elements (x:xs)
one by one. For each element, we test against name1
and name2
supplied, and if found replace the output number with the matching number.
Notes:
Maybe
value insteadfindNumberIter
, and hides it so that the user interface is cleanerx
in the list is split out into separate values using a pattern matchUpvotes: 0