簡體   English   中英

Haskell錯誤:“沒有使用'=='產生的實例(Eq Time)

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM