【问题标题】:Eq Ord Classes Haskell DataEq Ord 类 Haskell 数据
【发布时间】:2022-11-21 03:46:28
【问题描述】:

现在我有另一个问题:

另一个子任务告诉我从 Eq 和 Ord 类派生一个 Currency 数据类型。

问题又是我不允许使用推导(Ord,Eq)。

我不知道如何比较每种货币。你有什么想法吗?你能向我解释一下以便我理解吗?

data Currency = Dollar Integer Integer | Yen Integer | Euro Integer Integer

instance Eq Currency where
...

instance Ord Currency where
...

【问题讨论】:

  • 目前尚不清楚您打算如何将美元与日元进行比较。您的程序应该从互联网或其他什么地方获取汇率吗?

标签: haskell


【解决方案1】:

一般来说,解决这类问题的方法是不要过度关注类型类机制。我建议你先写一个像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 类型类做同样的事情。对于Ordthe minimal complete definition 定义<=compare,因此您应该选择其中之一。例如,您可以定义:

leqCurrency :: Currency -> Currency -> Bool
leqCurrency ...

再一次,您会问自己同样的问题:如果我有两个 Dollar 金额,什么时候一个比另一个少?如果我有一个Euro和一个Yen,哪个比另一个小?我无法为您回答这些语义问题,但您将使用您的答案对各种情况进行编码,完成后,您可以填写类型类:

instance Ord Currency where
  (<=) = leqCurrency

【讨论】:

  • 我认为您有错字——在最后的代码块中,Eq 应该是 Ord
【解决方案2】:

我不知道如何比较每种货币

我也不。 “应该如何比较货币”与其说是实施问题,不如说是设计问题。

如果您想获得完全正确的结果,则必须使用互联网下载当前汇率才能进行比较。但是EqOrd 实例根本不允许互联网连接,所以这实际上是不可能的。

听起来这是为了练习,所以为您的程序选择一些固定汇率也许是公平的?谷歌告诉我,在撰写本文时,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)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-08-29
    • 1970-01-01
    • 1970-01-01
    • 2017-04-03
    • 1970-01-01
    • 2023-04-07
    • 1970-01-01
    相关资源
    最近更新 更多