【发布时间】:2010-10-15 18:41:05
【问题描述】:
我想让所有作为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 创建了一个实例,只是对Enum 和Bounded 进行类型检查,而不是仅仅在Enum 和Bounded。这实际上意味着我正在为所有类型 :( 定义一个实例。
另一种方法是我必须编写独立的函数来提供我想要的行为,并为我想成为Random 实例的每种类型编写一些样板:
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
还有更好的选择吗?我应该如何处理这个问题?我什至不应该尝试这个吗?我是否过度担心样板文件?
【问题讨论】:
标签: haskell types typeclass instances