Haskell 哈斯凯尔错误:“;没有因使用'==';
我是Haskell的新手,我不明白为什么我不能比较这两个变量。 我有这个功能:Haskell 哈斯凯尔错误:“;没有因使用'==';,haskell,Haskell,我是Haskell的新手,我不明白为什么我不能比较这两个变量。 我有这个功能: nextMinute :: Date -> Time -> DateTime nextMinute date time = if time == Time 23 59 then DateTime (tomorrow date) newDay else DateTime date (timeSucc time) 我
nextMinute :: Date -> Time -> DateTime
nextMinute date time = if time == Time 23 59
then DateTime (tomorrow date) newDay
else DateTime date (timeSucc time)
我收到以下错误消息:
Time.hs:88:32:
No instance for (Eq Time) arising from a use of ‘==’
In the expression: time == Time 23 59
In the expression:
if time == Time 23 59 then
DateTime date newDay
else
DateTime date (timeSucc time)
In an equation for ‘nextMinute’:
nextMinute date time
= if time == Time 23 59 then
DateTime date newDay
else
DateTime date (timeSucc time)
您不必使用
==
,只需进行模式匹配即可:
nextMinute :: Date -> Time -> DateTime
nextMinute date (Time 23 59) = DateTime (tomorrow date) newDay
nextMinute date time = DateTime date (timeSucc time)
将
Eq
添加到您的Time
类型中可能很好,但没有特别的需要,因为模式匹配有一个同样好的解决方案。相等比较在Haskell中有点代码味道。如果你发现自己使用它,总是考虑是否应该更好地使用模式匹配,正如AM合金的答案。模式匹配往往更有效,而且即使在真正不可能相等的情况下(例如,在无限长列表上†)通常仍然有效
除此之外,在我看来,有些类型的情况下,你最好完全避免任何平等的假设。这包括表示某些连续物理量的所有类型,例如时间。从数学上讲,有两个这样的值。从更实际的角度来看,您的方法存在这样的风险:如果您以某种方式超出了准确值23:59
(例如,在检查日期转换之前加上一分一秒),那么换行将永远不会发生
因此,我建议仅将此类值与较小/较大运算符进行比较
nextMinute :: Date -> Time -> DateTime
nextMinute date time
| h' >= 24 = DateTime (tomorrow date) newDay
| otherwise = DateTime date naïveSucc
where naïveSucc@(Time h' _) = timeSucc time
†事实上,无限长列表上的相等问题与实数上的相等问题大致相同,如果您将它们描绘为无限长十进制展开式。当然,我们通常使用的数字类型实际上并不是无限精度的,但奇怪的是,假装这样通常会有帮助:实际上,浮点数会受到各种令人讨厌的不确定性问题的影响,但如果你只是简单地不尝试比较所有数字,而只是一个惰性的选择,那么你基本上就没事了
正如dfeuer所说,你也可以直接比较
Time
s和Time
Where's from?对不起,时间和其他参数是在别处声明的,我也应该发布它们吗?你可能只需要在Time
的定义中添加派生(Eq…)
(我想你已经有了派生(Show)
所以它是派生(Show,Eq)
啊,天哪,谢谢你!!你已经帮了我这个问题了!:D时间声明如下:数据时间=时小时分钟派生(Show)必须是数据时间=时小时分钟派生(Show,Eq)是的,谢谢大家!
data Time = Time { ... }
deriving (Show, Eq, Ord)