4
我想讓所有類型爲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
有沒有更好的方法?我應該如何處理這個問題?我甚至不應該試圖這樣做嗎?我過分擔心樣板嗎?