W Haskell, Czy istnieje "standardowa" biblioteka/pakiet do generowania enumeracji Random
/Arbitrary
?Haskell: "instancja (Enum a, Bounded a) => Losowo a" i "= Arbitralnie a"
Napisałem poniższy kod, ale nie mogę uwierzyć, że jestem pierwszą osobą, która ma tę potrzebę lub rozwiązała ją (i nie jestem pewien, czy moje rozwiązanie jest całkowicie poprawne). Mam również nadzieję, że istniejące rozwiązanie ma przy nim inne miłe funkcje.
Oto parę funkcji wybrać losową wartość od typu ENUM:
enumRandomR :: (RandomGen g, Enum e) => (e, e) -> g -> (e, g)
enumRandomR (lo,hi) gen =
let (int, gen') = randomR (fromEnum lo, fromEnum hi) gen in (toEnum int, gen')
enumRandom :: (RandomGen g, Enum e) => g -> (e, g)
enumRandom gen =
let (int, gen') = random gen in (toEnum int, gen')
i oto przypadki dla System.Random.Random
i Test.QuickCheck.Arbitrary
{-# LANGUAGE FlexibleInstances, UndecidableInstances, OverlappingInstances #-}
instance (Enum a, Bounded a) => Random a where
random = enumRandom
randomR = enumRandomR
instance (Enum a, Bounded a) => Arbitrary a where
arbitrary = choose (minBound, maxBound)
Oto przykład Bounded
, Enum
typ
data Dir = N | E | S | W
deriving (Show, Enum, Bounded)
A oto test losowe/metody arbitralne
> import Test.QuickCheck
> sample (arbitrary:: Gen Dir)
N
E
N
S
N
E
W
N
N
W
W
Nie jestem zachwycony, że moje rozwiązanie opiera się na tych rozszerzeniach:
{-# LANGUAGE FlexibleInstances, UndecidableInstances, OverlappingInstances #-}"
ponieważ:
- Constraint is no smaller than the instance head
in the constraint: Enum a
(Use -XUndecidableInstances to permit this)
,
- Overlapping instances for Random Int
arising from a use of `randomR'
Matching instances:
instance Random Int -- Defined in System.Random
instance (Enum a, Bounded a) => Random a
, oraz
- Illegal instance declaration for `Random a'
(All instance types must be of the form (T a1 ... an)
where a1 ... an are *distinct type variables*,
and each type variable appears at most once in the instance head.
Use -XFlexibleInstances if you want to disable this.)
Czy istnieje lepszy sposób? Czy moje rozwiązanie zawodzi w przypadku niektórych (bardziej "egzotycznych") typów ograniczonej enum niż mój prosty przykład?
Przyjęto odpowiedź hammara na udzielenie obejścia. Wznowiono wszystkie trzy odpowiedzi, aby uzyskać dobrą radę. Dziękuję Ci! – misterbee
Henning miał podobny pomysł na enumRandom: http://www.haskell.org/pipermail/libraries/2007-December/008725.html – misterbee
Używanie 'FlexibleInstances', takich jak' FlexibleContexts' i 'MultiParamTypeClasses', nie jest czymś w rodzaju być niezadowolonym z. –