当前位置:  开发笔记 > 小程序 > 正文

声明具有完整定义的子类

如何解决《声明具有完整定义的子类》经验,为你挑选了1个好方法。

我正在尝试执行以下操作:

-- enum which wraps arround
class (Enum a, Bounded a) => CyclicEnum a where
    next, prev :: a -> a

-- for equatable types this is readily implemented
instance (Enum a, Bounded a, Eq a) => CyclicEnum a where
    next x | x == maxBound = minBound
           | otherwise     = succ x

    prev x | x == minBound = maxBound
           | otherwise     = pred x

但是除非我同时启用FlexibleInstances和UndecidableInstances,否则这不会编译,这似乎不对.什么是正确的方法(即,通常使用的方法,最好没有语言扩展)来做这样的事情?有吗?



1> leftaroundab..:

首先,没有任何错误FlexibleInstances- 它只是禁用标准Haskell的一些限制,这些限制主要是出于历史原因,也许是为了使编译器更容易编写.但是,如果你只使用GHC - 几乎每个人都这样做 - 那么没有真正的理由不使用FlexibleInstances.

UndecidableInstances 更值得商榷,但在某些情况下,使用它也绝对可以.

但是,在您的示例中,我认为不需要定义任何新的类型类!为什么不直接定义为自由函数,

next, prev :: (Enum a, Bounded a, Eq a) => a -> a
next x | x == maxBound = minBound
       | otherwise     = succ x
prev x | x == minBound = maxBound
       | otherwise     = pred x

好.可能你的意图是CyclicEnum除了通用实例之外还添加其他实例.但这实际上是不可能的!即使有UndecidableInstances.它需要OverlappingInstances(或者更确切地说,Overlappablepragma),但重叠的实例实际上不是你应该使用的东西,因为你可以.


注意,如果你想要你可以为这个约束定义一个名为`CyclicEnum`的同义词,就像这样`类型CyclicEnum a =(Enum a,Bounded a,Eq a)`只是为了便于阅读.实际上,如果你很聪明,你就不需要Eq,因为Enum会给你一个诱导的命令,但这就是重点.
@ user2407038对,虽然`类型CyclicEnum = ...`需要`ConstraintKinds`.现在,这也是一个完全没有问题的扩展,但由于它仍然是如此新颖,它还没有被接受.许多人仍然有GHC <7.4,唉......
推荐阅读
吻过彩虹的脸_378
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有