我有這段代碼,在我看來它太長了。我想知道是否有辦法簡化或縮短它。
我有這個輔助函式swap,它接收兩個整數串列,并在將一個數字從 on 交換到另一個串列后回傳它們。所有串列中有 5 個整數,所以如果少于這個,我用零填充。
它看起來像這樣:
-- Takes in two lists and moves one non-zero int from one to the other
swap :: [Int] -> [Int] -> [[Int]]
swap xs ys
| xs == ys = [xs, ys] -- If both lists are all zeroes
| all (==0) ys = -- If the second list is all zeroes
let
e = head $ filter (/= 0) xs -- First non-zero element from first list
newX = replicate (length xs - length (filter (/= 0) xs) - 1) 0 tail (filter (/= 0) xs)
newY = tail ys [e]
in
[newX, newY]
| otherwise =
let
e = head $ filter (/= 0) xs -- First non-zero element from first list
newX = replicate (length xs - length (filter (/= 0) xs) 1) 0 tail (filter (/= 0) xs)
newY = replicate (length (filter (==0) ys) - 1) 0 [e] drop (length xs - length (filter (/= 0) ys)) ys
in
[newX, newY]
我在下面的函式中使用它,這是我覺得太長的函式:
move :: Int -> Int -> [[Int]] -> [[Int]]
move a b ints
| a == b = error "a and b cannot be the same integer"
| a == 1 && b == 2 =
let
fst = ints !! (a-1)
snd = ints !! (b-1)
swapped = swap fst snd
in
[head swapped, last swapped, last ints]
| a == 1 && b == 3 =
let
fst = ints !! (a-1)
snd = ints !! (b-1)
swapped = swap fst snd
in
[head swapped, ints !! 1, last swapped]
| a == 2 && b == 1 =
let
fst = ints !! (a-1)
snd = ints !! (b-1)
swapped = swap fst snd
in
[last swapped, head swapped, last ints]
| a == 2 && b == 3 =
let
fst = ints !! (a-1)
snd = ints !! (b-1)
swapped = swap fst snd
in
[head ints, head swapped, last swapped]
| a == 3 && b == 1 =
let
fst = ints !! (a-1)
snd = ints !! (b-1)
swapped = swap fst snd
in
[last swapped, ints !! 1, head swapped]
| a == 3 && b == 2 =
let
fst = ints !! (a-1)
snd = ints !! (b-1)
swapped = swap fst snd
in
[head ints, last swapped, head swapped]
| otherwise = error "a and b must be either 1, 2 or 3"
此函式接受兩個整數和一個由 3 個整數串列組成的串列,其中每個串列有 5 個整數,因此示例輸入將是 f.ex
[[1,2,3,4,5],[0,0,0,0,0],[0,0,0,0,0]] or
[[0,0,0,4,5],[0,0,0,2,3],[0,0,0,0,1]] or
[[0,0,3,4,5],[0,0,0,0,1],[0,0,0,0,2]]
所以 $a$ 和 $b$ 只能是 1,2 或 3。給我 $2^3=6$ 不同的情況來考慮。即使設法將其簡化為 $a>b$ 和 $b>a$ 兩種情況,與我期望的適合 Haskell 的代碼相比,我仍然會得到太多的代碼行。有沒有辦法縮短這段代碼?
uj5u.com熱心網友回復:
這還不是一個完整的答案,而是一個的開始。看看我如何將所有代碼重復洗掉到where塊中。仍然有很多簡化的機會。
-- Takes in two lists and moves one non-zero int from one to the other
swap :: [Int] -> [Int] -> [[Int]]
swap xs ys
| xs == ys = [xs, ys] -- If both lists are all zeroes
| all (==0) ys = -- If the second list is all zeroes
let
newX = replicate (length xs - length nonZeroXs - 1) 0 tail nonZeroXs
newY = tail ys [e]
in
[newX, newY]
| otherwise =
let
newX = replicate (length xs - length nonZeroXs 1) 0 tail nonZeroXs
newY = replicate (length (filter (==0) ys) - 1) 0 [e] drop (length xs - length (filter (/= 0) ys)) ys
in
[newX, newY]
where
nonZeroXs = filter (/= 0) xs
e = head $ filter (/= 0) xs -- First non-zero element from first list
newX之間的唯一區別是最終添加的信號。這表明整個決策塊可能不在最佳位置。
move :: Int -> Int -> [[Int]] -> [[Int]]
move a b ints
| a == b = error "a and b cannot be the same integer"
| a == 1 && b == 2 = [head swapped, last swapped, last ints]
| a == 1 && b == 3 = [head swapped, ints !! 1, last swapped]
| a == 2 && b == 1 = [last swapped, head swapped, last ints]
| a == 2 && b == 3 = [head ints, head swapped, last swapped]
| a == 3 && b == 1 = [last swapped, ints !! 1, head swapped]
| a == 3 && b == 2 = [head ints, last swapped, head swapped]
| otherwise = error "a and b must be either 1, 2 or 3"
where
fst = ints !! (a-1)
snd = ints !! (b-1)
swapped = swap fst snd
仔細看看上面的內容并運行一些測驗。我現在沒有時間親自測驗。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/342914.html
標籤:哈斯克尔
上一篇:如何讓cabal使用本地版本的包作為Hackage包的依賴項?
下一篇:HaskellADT相互依賴
