我有這個日期型別:
data Storage = HDD String Int Int | SSD String Int deriving (Eq, Show)
HDD (生產者) (RPM) (容量) | SSD(生產者)(容量)
我的任務是在此函式中列出所有大于最大 SSD 容量的 HDD(如果沒有 SSD,則列出所有 HDD):
hugeHDDs :: [Storage] -> [Storage]
這是我嘗試創建可提供最大 SSD 容量的功能:
maxSSD :: [Int] -> Int
maxSSD = foldr f 0
where f a (cap (SSD c b)) = max a (cap (SSD c b))
cap :: Storage -> Int
cap (SSD _ b) = b
但它不起作用,即使它會,我真的不知道如何繼續前進
uj5u.com熱心網友回復:
由于這是家庭作業,我更愿意輕推你,而不是給你完整的答案。讓我們從“它不起作用”部分開始:
maxSSD :: [Int] -> Int
maxSSD = foldr f 0
where f a (cap (SSD c b)) = max a (cap (SSD c b))
然后我們看一下foldr簽名:
foldr :: (a -> b -> b) -> b -> [a] -> b
你正在尋找一個[Int]并減少到一個Int. 根據您的函式名稱,您希望輸入 SSD 容量串列并找到最小的容量。
我認為您稍微偏離軌道的地方是,您提供給 foldr 的功能突然嘗試處理SSD型別,而它沒有一個開始。如果要創建 SSD,則需要為其提供生產者和容量。您的函式中有一個 SSD 的構造f函式,但是您在建構式中添加了什么?
SSD c b
從語法上講,這是有效的 haskell,但如果 c 和 b 沒有定義,那么編譯器就會抱怨。如果它們被定義,它們將永遠是相同的。這意味著它們對您撰寫的函式完全沒有幫助。
您可能會以不同的方式考慮這個問題:
想想你想從maxSSD函式中得到什么。您想獲取 SSD 的串列,如果沒有 SSD,則沒有最大值。如果有SSD,則取最大的容量。
這表示您的函式簽名可能看起來更像:
maxSSD :: [SSD] -> Int
習慣上,使用 可能會更好maxSSD :: [SSD] -> Maybe Int,但我們現在可以保持簡單。
當你實作這個函式時,你可以先用簡單的遞回來撰寫它:
maxSSD [] = 0
maxSSD ((SSD _ cap):xs) = ...
然后僅在您明確了解遞回時才使用 foldr 。
uj5u.com熱心網友回復:
任務看起來像這樣(它現在正在“作業”)
data Storage = HDD String Int Int | SSD String Int deriving (Eq, Show)
capacity :: Storage -> Int
capacity (HDD _ _ a) = a
capacity (SSD _ b) = b
isHDD :: Storage -> Bool
isHDD (HDD _ _ _) = True
isHDD (SSD _ _) = False
maxSSD :: [Storage] -> Int
maxSSD [] = 0
maxSSD [(SSD _ c)] = c
maxSSD [(HDD _ _ _)] = 0
maxSSD (x:xs)
|(capacity x >= capacity (head xs)) && ((isHDD x) == False) && ((isHDD (head xs)) == False) = maxSSD (x:(tail xs))
|otherwise = maxSSD xs
hugeHDDs :: [Storage] -> [Storage]
hugeHDDs [] = []
hugeHDDs (x:xs)
|(isHDD x == True) && ((capacity x) > (maxSSD xs)) = (x:(hugeHDDs xs))
|otherwise = hugeHDDs xs
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/528494.html
標籤:哈斯克尔
