繁体   English   中英

如何在Haskell中更新列表中的特定元组?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM