我想写的不安全Enum
功能总版本:安全和多态的枚举哈斯克尔
predMay :: Enum a => a -> Maybe a
succMay :: Enum a => a -> Maybe a
toEnumMay :: Enum a => Int -> Maybe a
我的问题是不安全的功能仅部分如果Enum
也Bounded
,所以安全版本应该有不同的形式,在两种情况下:
predMayUnboundedEnum :: Enum a => a -> Maybe a
predMayUnboundedEnum = Just . pred
predMayBoundedEnum :: (Enum a, Bounded a) => a -> Maybe a
predMayBoundedEnum x
| fromEnum x == fromEnum (minBound `asTypeOf` x) = Nothing
| otherwise = Just (pred x)
我已经得到我想要的功能,最好的办法是用另一种类型类:
class Enum a => SafeEnum a where
predMay :: a -> Maybe a
instance Enum a => SafeEnum a where
predMay = predMayUnboundedEnum
instance (Enum a, Bounded a) => SafeEnum a where
predMay = predMayBoundedEnum
但这会引起关于Duplicate instance declarations
的投诉。
我在这里有没有正确的想法,还是有更好的方法来解决这个问题?有其他人已经完成了吗? (我知道包prelude-safeenum,但Enum
对我的主要优点是我们可以deriving
它)。这些安全功能甚至可能,或者是野外太多,以至于不能让这样一个简单的解决方案安全?
我建议你写你自己的类,并使用'DefaultSignatures'自动“派生”它(即你会写'实例SafeEnum X'了在'ghc8'中使用'DeriveAnyClass',你甚至可以写'数据X,其中...派生(SafeEnum)',这就等同于上面的例子。你的问题是你想*决定*如果一个类型有一个实例,这根本不可能 - 它违背了类的语义。另外,Enum通常被认为是完全无法执行的,所以你可能会发现你对Enum/Bounded的假设并不总是成立。 – user2407038