【问题标题】:Haskell custom data type, instance Num, and redundancyHaskell 自定义数据类型、实例 Num 和冗余
【发布时间】:2015-02-23 11:26:05
【问题描述】:

我正在 Haskell 中开发一小组举重实用程序作为学习练习。我已经定义了一个数据类型Weight 这样:

data Weight = Wt Float Unit 
              deriving (Show, Eq)

data Unit   = Lb | Kg 
              deriving (Show, Eq)

instance Num Weight where
  Wt x Lb + Wt y Lb = Wt (x + y) Lb
  Wt x Lb * Wt y Lb = Wt (x * y) Lb
  negate (Wt x Lb)  = Wt (negate x) Lb
  abs    (Wt x Lb)  = Wt (abs x) Lb
  signum (Wt x Lb)  = Wt (signum x) Lb
  fromInteger x     = Wt (fromInteger x) Lb
  -- Repeat for Kg...

有没有办法在 Num 实例定义中为 Unit 指定泛型类型?最好指定如下内容:

instance Num Weight where
  Wt x a + Wt y a = Wt (x + y) a
  -- ...

而不是使用其他构造函数重复所有内容。

【问题讨论】:

  • 当心!公斤是质量单位,不是重量。 SI(派生)重量单位是牛顿,等于 1 kg m/s^2。
  • 您是否允许将 Kg 和 Lb 加在一起?否则,考虑使用幻像类型来静态保证这不会发生。

标签: haskell types instance


【解决方案1】:

您可以使用警卫。下面的代码是一个错误,我相信你已经注意到了:

instance Num Weight where
    Wt x a + Wt y a = Wt (x + y) a
    -- ...

但这很好:

instance Num Weight where
    Wt x a + Wt y b | a == b = Wt (x + y) a
    -- ...

请记住,如果有人试图将公斤与磅相加,除非您也处理这种情况,否则您的代码会出错。

【讨论】:

  • 完美,谢谢!我有一个convert 函数,所以我应该能够执行以下操作:Wt x a + Wt y b | a == b = Wt (x + y) a otherwise = Wt x a + (convert (Wt y b)) 对吗?
  • 看来应该可以了。只是不要忘记otherwise 子句需要一个换行符和另一个竖线。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-03
  • 2011-12-20
  • 2013-11-25
  • 1970-01-01
  • 1970-01-01
  • 2015-12-09
相关资源
最近更新 更多