我想撰寫一個函式來修改串列中的某些元素,只有當它們是某個值時。
例如,對于等于 10 的每個數字,我想將串列中接下來的兩個數字添加到該原始數字。所以如果我有:[10, 9, 1, 8, 2, 10, 10, 6, 4, 5, 4, 7, 3, 3, 4, 3, 7, 1]
然后我想要一個將回傳的函式:[20, 9, 1, 8, 2, 26, 20, 6, 4, 5, 4, 7, 3, 3, 4, 3, 7, 1]
我探索過使用地圖來執行此操作,但我看不到如何獲取地圖以使用串列中接下來的兩個元素將它們添加到我要修改的元素中。
到目前為止,這是我的代碼。我知道重用 x:y:z 不變的值顯然有缺陷
bowling :: [Int] -> [Int]
bowling (x:y:z:xs) = map (\x -> if (x == 10) then x y z else x) xs
b1 = bowling [10, 9, 1, 8, 2, 10, 10, 6, 4, 5, 4, 7, 3, 3, 4, 3, 7, 1]
我嘗試使用地圖來解決問題,但我不知道如何創建一個函式來使用串列中接下來的兩個元素。
uj5u.com熱心網友回復:
這確實是不可能的map。不過,您可以使用顯式遞回來完成,如下所示:
bowling :: [Int] -> [Int]
bowling [] = []
bowling (x:xs) = case x of
10 -> case xs of
y:z:_ -> x y z:bowling xs
_ -> error "Uh oh, got a 10 but one or both of the next two numbers to add were missing"
_ -> x:bowling xs
如果你真的想用高階函式來做這件事,你可以使用mapAccumRorpara來代替。例如,與mapAccumR:
import Data.Traversable (mapAccumR)
bowling :: [Int] -> [Int]
bowling = snd . mapAccumR go (uhoh,uhoh) where
go :: (Int,Int) -> Int -> ((Int,Int), Int)
go ~(y,z) x = ((x,y), if x == 10 then x y z else x)
uhoh :: Int
uhoh = error "Uh oh, got a 10 but one or both of the next two numbers to add were missing"
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/536670.html
標籤:列表哈斯克尔
下一篇:在haskell中左關聯一個操作
