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