[英]How can I update a specific tuple in a list in Haskell?
我是初学者是Haskell,我正在尝试创建一个函数,可以提高具有特定初始值的人的工资,如下所示:
*Main> giveRaise 'A' 200 [('A',"Al",1000),('B',"Bob",1500)]
哪个会给出答案:
[('A',"Al",1200),('B',"Bob",1500)]
到目前为止我的代码是这样的,但是当我尝试用n来提高初始'g'时,我一直收到错误:
giveRaise :: Char -> Int -> [(Char, String, Int)] -> [(Char, String, Int)]
giveRaise g n [(g, z, m)]
= [(g, z, (m + n))]
您将修改列表中的任意元素,因此最糟糕的情况是您必须循环 。 由于递归是在Haskell中循环的方式,因此编写giveRaise
一个子句是很奇怪的。 使用递归时,您总是有两种类型的子句:
基本案例很简单:
giveRaise pa n ((pb,z,m):tail) | pa == pb = (pb,z,m+n):tail
在Prolog中,您可以在头部和统一中使用相同的变量(在Erlang中,检查相等性)。 在Haskell中不允许这样做。 在Haskell中,使用守卫 (如| pa == pb
)来确定这两个人是否相同。
现在还有另一种选择: pa
不是pb
。 在otherwise
情况下,我们执行递归并在列表中进一步搜索,因此:
| otherwise = (pb,z,m):giveRaise pa n tail
或者把它们放在一起:
giveRaise pa n ((pb,z,m):tail) | pa == pb = (pb,z,m+n):tail
| otherwise = (pb,z,m):giveRaise pa n tail
我们必须考虑最后一个案例:如果我们到达列表的末尾并且没有找到该人,该怎么办? 我们可以简单地忽略它并返回空列表,如:
giveRaise _ _ [] = []
或者我们可以抛出error
:
giveRaise _ _ [] = error "Could not give a raise."
所以我们可以实现它:
giveRaise pa n ((pb,z,m):tail) | pa == pb = (pb,z,m+n):tail
| otherwise = (pb,z,m):giveRaise pa n tail
giveRaise _ _ [] = error "Could not give a raise."
最后请注意,此函数仅向具有给定标识符的第一个人进行加注 。 并非所有具有该标识符的人 。 但我假设标识符是唯一的。
“做点列表中的一个元素”是一样的“做别的事情列表中的每个元素”,在别的事情做了 ,当元素就是你要找的人并没有什么时,它不是。 换句话说,将此操作构造为map
是有意义的。
giveRaise :: Char -> Int -> [(Char, String, Int)] -> [(Char, String, Int)]
giveRaise x amt = map raise
where raise (y, n, salary)
| x == y = (y, n, salary + amt)
| otherwise = (y, n, salary)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.