我要使所有类型都是
Enum
和
Bounded
也是
Random
. 以下代码可以做到这一点,并且应该可以工作(启用适当的扩展名):
import System.Random
instance (Enum r, Bounded r) => Random r where
randomR (hi, lo) = inFst toEnum . randomR (fromEnum hi, fromEnum lo)
where inFst f (x,y) = (f x, y)
random = randomR (maxBound, minBound)
但我知道这是不好的风格,因为
instance (Enum r, Bounded r) => Random r
为所有人创建一个实例
r
,只需类型检查
枚举
和
有界
而不仅仅是将实例放在
枚举
和
有界
. 这实际上意味着我正在为所有类型定义一个实例
:(
.
另一种方法是,我必须编写独立的函数,为我想要的行为提供支持,并为每种类型编写一些样板文件
随机的
:
randomBoundedEnum :: (Enum r, Bounded r, RandomGen g) => g -> (r, g)
randomBoundedEnum = randomRBoundedEnum (minBound, maxBound)
randomBoundedEnumR :: (Enum r, Bounded r, RandomGen g) => (r, r) -> g -> (r, g)
randomBoundedEnumR (hi, lo) = inFst toEnum . randomR (fromEnum hi, fromEnum lo)
where inFst f (x,y) = (f x, y)
data Side = Top | Right | Bottom | Left
deriving (Enum, Bounded)
-- Boilerplatey :(
instance Random Side where
randomR = randomBoundedEnumR
random = randomBoundedEnum
data Hygiene = Spotless | Normal | Scruffy | Grubby | Flithy
deriving (Enum, Bounded)
-- Boilerplatey, duplication :(
instance Random Hyigene where
randomR = randomBoundedEnumR
random = randomBoundedEnum
有更好的选择吗?我应该如何处理这个问题?难道我不应该尝试这个吗?我是不是过于担心样板?