如何更新元组列表中的元素?

How can I update an element in a tuple list?

我是 Haskell 的新手,我正在尝试更新元组列表中的元素。我的元组列表是 [(String, Int)] 类型的,如果我得到的字符串在列表中,我只想将整数减 -1,否则我必须 return 没什么,我尝试做:

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

例如,如果我有 [("l1",10), ("l2",20), ("l3",30)] 并且想要更新“l2”,函数必须 return [("l1",10), ("l2",19), ("l3",30)],但我的函数 return [("l2",19), ("l3",30)]

| otherwise = myFunc s xs

在这里,我们丢弃列表的第一个元素。这可能不是您想要的。考虑

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

如果我们没有找到匹配项,我们不想丢弃该元素;我们想将其保留在列表中不加修改。因此,我们 运行 递归调用,然后将当前元素原封不动地重新添加到前面。

如果您来自命令式语言,您可能会担心此函数不是尾递归的,这是公平的。您的原始函数是尾递归的,但这个函数不是。请参阅 the Haskell Wiki 以获得关于为什么我们通常不关心 Haskell 的一个很好的解释。