5

我最近一直在尝试“向我学习 Haskell”,并且我想创建一个新类型来表示整数状态,而不仅仅是使用原始整数(为了类型安全和代码清晰)。具体来说,编译以下代码:

newtype AuxState = AuxState Integer
  deriving (Eq, Ord, Num, Integral, Real, Enum)

但是,由于我的应用程序中有无数个状态,因此我没有兴趣将此状态转换为 Enum。但是,如果我尝试删除该deriving (Enum)语句,那么它只是deriving (Eq, Ord, Num, Integral, Real),编译器会抱怨:

No instance for (Enum AuxState)
  arising from the 'deriving' clause of a data type declaration
Possible fix:
  add an instance declaration for (Enum AuxState)
  or use a standalone 'deriving instance' declaration,
       so you can specify the instance context yourself
When deriving the instance for (Integral AuxState)

我很难相信 Haskell 会强制 Integral 类中的类型也属于 Enum 类。不应该反过来吗?这是有原因的,还是我做/理解错了什么?

4

2 回答 2

8

所有Integral这些都是必然Enum的,因为Integral数学的基础是succpred运算。(我认为,从技术上讲Enum,它代表了一个适当的类型层次结构,其中一个Integral类型是一个数学半群。)反过来似乎更错误:你的意思是每个都Enum应该是Integral?这是否包括随机 ADT,例如

data Foo = A | B | C | D | E | F | G deriving (Enum)

?

(当然,每个都Enum应该与 的子集同构Integral,但这实际上表明它朝另一个方向发展: Integral可以表示任何Enum但不能反之亦然,Integralur- 的种类也是如此Enum。)

于 2012-04-11T04:37:26.313 回答
6

技术原因是因为Integral定义Prelude如下:

class (Real a, Enum a) => Integral a where
   ...

数学上的原因是每个整数类型都是可枚举的,但反之则不然。例如考虑有理数。请注意,Enum 并不意味着如 所示的有限枚举Integer

于 2012-04-11T05:54:45.110 回答