jua*_*cho 0 haskell operator-overloading custom-data-type
我有以下数据声明来代表温度:
data Temp = Kelvin Float | Celsius Float | Fahrenheit Float deriving Show
-- Functions for conversion between temperatures
kelvToCels :: Temp -> Temp
kelvToCels (Kelvin k) = Celsius (k-273.15)
kelvToFahr :: Temp -> Temp
kelvToFahr (Kelvin k) = Fahrenheit (((9/5)*(k-273.15))+32)
celsToKelv :: Temp -> Temp
celsToKelv (Celsius c) = Kelvin (c+273.15)
celsToFahr :: Temp -> Temp
celsToFahr (Celsius c) = Fahrenheit (((9/5)*c)+32)
fahrToKelv :: Temp -> Temp
fahrToKelv (Fahrenheit f) = Kelvin ((5/9)*(f-32)+273.15)
fahrToCels :: Temp -> Temp
fahrToCels (Fahrenheit f) = Celsius ((f-32)/(9/5))
Run Code Online (Sandbox Code Playgroud)
我希望能够比较温度,这样
> (Celsius 100) == (Fahrenheit 212.0)
评估为true。
这是我的尝试:
instance Eq Temp where
Celsius c == Fahrenheit f =
(celsToFahr c) == f
Run Code Online (Sandbox Code Playgroud)
结果:ghci错误,因为RHS上的c和f是Floats而不是Temps,因此这里是一个“修复”:
instance Eq Temp where
Celsius c == Fahrenheit f =
(celsToFahr (Celsius c)) == (Fahrenheit f)
Run Code Online (Sandbox Code Playgroud)
编译没有错误,但是(Celsius 100) == (Fahrenheit 212.0)
引发了异常:函数==中的非穷举模式
我还想创建一个Ord实例,以compare类似的方式重新定义。
我已经走到了尽头,我找不到与我类似的任何示例,因此非常感谢任何建议。提前致谢。
Dan*_*ner 11
我建议您不要写不完整的模式匹配。考虑一下这对您的xToY功能意味着什么,这意味着它们应该能够处理任何输入-因此它们的名称应更改为just toY。
我还要保证通过返回一个Float(显然不能用错误的构造函数标记)而不是一个Temp(可以)来知道使用哪个构造函数。所以:
toKelvin :: Temp -> Float
toKelvin (Fahrenheit f) = (5/9)*(f-32)+273.15
toKelvin (Celsius c) = c+273.15
toKelvin (Kelvin k) = k
Run Code Online (Sandbox Code Playgroud)
toCelsius和和类似toFahrenheit。如果您确实想要,则可以分别编写类似
normalizeKelvin :: Temp -> Temp
normalizeKelvin = Kelvin . toKelvin
Run Code Online (Sandbox Code Playgroud)
但是这是否明智,在很大程度上取决于您打算如何使用此代码。
鉴于此,我们现在可以Eq通过选择一个比例尺作为自然比例尺并将其转换为*来编写一个非递归实例。所以:
instance Eq Temp where
t == t' = toKelvin t == toKelvin t'
Run Code Online (Sandbox Code Playgroud)
请注意,这里我们从调度Temp实例的Float实例Eq,当我们打电话(==),不像你的代码,它从派遣Temp实例回到另一个调用Temp的实例Eq。
*如果对四舍五入有偏执,可以先检查是否完全需要转换。所以:
instance Eq Temp where
Fahrenheit f == Fahrenheit f' = f == f'
Celsius c == Celsius c' = c == c'
t == t' = toKelvin t == toKelvin t'
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
85 次 |
| 最近记录: |