一般来说,解决这类问题的方法是不要过度关注类型类机制。我建议你先写一个像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,the minimal complete definition 定义<= 或compare,因此您应该选择其中之一。例如,您可以定义:
leqCurrency :: Currency -> Currency -> Bool
leqCurrency ...
再一次,您会问自己同样的问题:如果我有两个 Dollar 金额,什么时候一个比另一个少?如果我有一个Euro和一个Yen,哪个比另一个小?我无法为您回答这些语义问题,但您将使用您的答案对各种情况进行编码,完成后,您可以填写类型类:
instance Ord Currency where
(<=) = leqCurrency