[英]Haskell error: "No instance fo (Eq Time) arising from a use of '=='
我對Haskell很新,我不明白為什么我無法比較這兩個變量。 我有這個功能:
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中有點代碼味道。 如果您發現自己使用它,請始終考慮是否應該更好地使用模式匹配,如amalloy的答案所示。 模式匹配往往更有效,並且即使在無法實現相等的情況下(通常在無限長度列表†上 ),通常仍然有效。
除此之外,IMO還有一些類型,你應該更好地避免任何平等假設。 這包括代表一些連續物理量的所有類型,例如確實是時間。 從數學上講,兩個這樣的值實際上永遠不相等 。 從更實際的角度來看,你的方法有風險,如果你以某種方式超過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
小號直接與<
,如果你讓一個Ord
實例。 與Eq
一樣,這可以自動導出
data Time = Time { ... }
deriving (Show, Eq, Ord)
但請注意:記錄字段需要按正確的順序排列才能使詞匯順序有意義(你不希望9:45 > 10:15
!)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.