Home > Enterprise >  How can I update an element in a tuple list?
How can I update an element in a tuple list?

Time:09-17

I'm new to Haskell and I'm trying to update an element in a tuple list. My tuple list is of type [(String, Int)], I only want to decrement the integer by -1 if the string I get is in the list, otherwise I have to return Nothing, i try to do:

myFunc :: String -> [(String, Int)] -> Maybe [(String, Int)]
myFunc s [] = Nothing 
myFunc s ((s2,i):xs)
           | s == s2 = Just ((s2, i - 1) : xs)
           | otherwise = myFunc s xs

For example, if I have [("l1",10), ("l2",20), ("l3",30)] and want update "l2", the function had to return [("l1",10), ("l2",19), ("l3",30)], but my function return [("l2",19), ("l3",30)]

CodePudding user response:

| otherwise = myFunc s xs

Here, we discard the first element of the list. That's likely not what you intended. Consider

| otherwise = fmap ((s2, i) :) $ myFunc s xs

If we don't get a match, we don't want to throw the element out; we want to leave it in the list unmodified. Hence, we run the recursive call and then prepend the current element back on, untouched.

If you're coming from a more imperative language, you might worry that this function isn't tail recursive, which is fair. Your original function is tail recursive but this one is not. See the Haskell Wiki for a good explanation as to why we generally don't care in Haskell.

  • Related