現在我有另一個問題:
另一個子任務告訴我從類中派生資料型別。
我不知道如何比較它。你有什么想法嗎?你能向我解釋一下以便我理解嗎?
``
實體 Eq 其中...
實體 Ord 哪里...
uj5u.com熱心網友回復:
一般來說,解決這類問題的方法是不要過度關注型別類機制。我建議你先寫一個像這樣的函式eqCurrency:
eqCurrency :: Currency -> Currency -> Bool
eqCurrency ...
顯而易見的下一步是輸入您的引數并進行一些模式匹配。例如,我可能會寫:
eqCurrency :: Currency -> Currency -> Bool
eqCurrency (Dollar d1 c1) (Dollar d2 c2) = ...
eqCurrency (Yen y1) (Yen y2) = ...
eqCurrency (Euro d1 c1) (Euro d2 c2) = ...
接下來,您必須決定如何檢查不同型別貨幣的相等性。那么,問問自己,是否存在美元金額等于日元金額的情況?如果是這樣,請為此撰寫案例。如果沒有,也許你可以添加一個包羅萬象的模式匹配,比如
eqCurrency _c1 _c2 = False
一旦你撰寫了這個函式并對它的行為感到滿意,你就可以將它插入到型別類中:
instance Eq Currency where
(==) = eqCurrency
您需要為Ord型別類做同樣的事情。對于Ord,最小的完整定義是定義<=或compare,因此您應該選擇其中之一。例如,您可以定義:
leqCurrency :: Currency -> Currency -> Bool
leqCurrency ...
再一次,你會問自己同樣的問題:如果我有兩Dollar筆錢,什么時候一筆比另一筆少?如果我有 aEuro和 a Yen,哪個比另一個小?我無法為您回答這些語意問題,但您將使用您的答案對各種情況進行編碼,完成后,您可以填寫型別類:
instance Ord Currency where
(<=) = leqCurrency
uj5u.com熱心網友回復:
我不知道如何比較每種貨幣
我也不。“應該如何比較貨幣”與其說是實施問題,不如說是設計問題。
如果您想獲得完全正確的結果,則必須使用互聯網下載當前匯率才能進行比較。但是實體根本不允許互聯網連接,所以這實際上是不可能的Eq。Ord
聽起來這是為了練習,所以為您的程式選擇一些固定匯率也許是公平的?谷歌告訴我,在撰寫本文時,1 美分值 1.4 日元,所以我接受它。
然后我們知道 ord 的一種情況:
instance Ord Currency where
compare (Dollar dollars cents) (Yen yen) = compare ((dollars*100 cents) * 1.4) yen
-- ...
Ord實體的其余部分可以用類似的方式填寫,例如compare (Yen ...) (Dollar ...)等等compare (Dollar ...) (Euro ...)等等。
該實施將起作用,并且值得完整填寫。
不過,如果您有興趣,還有一個“更清潔”的解決方案。我們可以選擇一些“錨定”貨幣,比如日元。然后我們可以撰寫一個所謂的“規范化”函式,將每種貨幣轉換為日元:
normalize :: Currency -> Integer
normalize (Dollar dollars cents) = (dollars*100 cents) * 1.4
-- you fill in the rest
使用這個,我們可以Ord更簡單地寫成
instance Ord Currency where
compare c1 c2 = compare (normalize c1) (normalize c2)
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/537527.html
標籤:哈斯克尔
上一篇:為什么運算式`foldr(mappend.Sum)1[2]`會進行型別檢查?
下一篇:顯示類Haskell
