如何有效地为类型类实例Eq

我制作了以下类来在不同的温度类型之间进行转换:

data Temp = Kelvin Float | Celsius Float |Fahrenheit Float deriving Show

conversionKelvin:: Temp -> Temp
conversionKelvin (Celsius x) = Kelvin (x + 273.15)
conversionKelvin (Fahrenheit x) = Kelvin((x - 32) * 5/9 + 273.15)
conversionKelvin (Kelvin x) = Kelvin x

conversionCelsius:: Temp -> Temp
conversionCelsius (Kelvin x) = Celsius (x - 273.15)
conversionCelsius (Fahrenheit x) = Celsius((x - 32) * 5/9)
conversionCelsius (Celsius x) = Celsius x

conversionFahrenheit:: Temp -> Temp
conversionFahrenheit (Celsius x) = Fahrenheit (x * 9/5 + 32)
conversionFahrenheit (Kelvin x) = Fahrenheit((x - 273.15)*9/5 + 32)
conversionFahrenheit (Fahrenheit x) = Fahrenheit x

到目前为止一切都很好,但是我想实现实例 Eq 和 Ord。我想过将每种类型转换为摄氏度,然后看看哪个更大,但我无法通过编译器。有什么帮助吗?

编辑:这是我在实例化 Eq 的尝试:

instance Eq Temp where
    a == b = conversionCelsius(a) == conversionCelsius(b)
instance Eq Temp where
    a == b = conversionCelsius(a) == conversionCelsius(b)

它编译但它使haskell进入某种循环(不打印输出)

回答

这导致无限递归

这是因为比较a == b的是这两种Temps,并且比较conversionCelsius(a) == conversionCelsius(b)再次两者TempS,所以我们永远递归。

要停止递归,您至少需要有一个基本情况,其中Temps之间的比较是通过比较Floats来完成的。一种可能的解决方案如下。

instance Eq Temp where
    Celsius x == Celsius y = x == y
    a         == b         = conversionCelsius a == conversionCelsius b

这将直接比较摄氏温度,比较它们的Float值。其他温度会在递归之前转换为摄氏度。递归之后,我们会立即找到基本情况,这样递归就结束了。


以上是如何有效地为类型类实例Eq的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>