daha uzun listeleri boş bir liste ya almak veya ters üretmek için oneof
kullanabilirsiniz:
olarak
λ> generate (arbitrary :: Gen (List Int))
Nil
λ> generate (arbitrary :: Gen (List Int))
Cons 4 (Cons 26 Nil)
λ> generate (arbitrary :: Gen (List Int))
Nil
açıklamalar: Burada
instance Arbitrary a => Arbitrary (List a) where
arbitrary =
oneof [nil, cons]
where nil = return Nil
cons = do
h <- arbitrary
tl <- arbitrary
return $ Cons h tl
birkaç testlerdir zeta, bunun açık bir kusura sahip olduğuna işaret etti. hasta muhtemelen çok kısa listeleri oluşturabilir:
- p (Nil) = 0,5
- p ((_
Cons
Nil) = 0,25
- p ((_
Cons
_ Cons
Nil) = 0,125
- .. .
0,5
Zeta da çözelti hav etmez bu olasılık ile Nil
çekecek şekilde e bu problem! İstersen
Sen frequency
kullanarak yerine oneof
bu olasılık adapte alabilirsiniz: Burada
frequency [(1,nil), (4,cons)]
Eğer p(Nil) = 0.2
ve p(Cons) = 0.8
olacak ama tabii ki sizin beğeninize bu uyum sağlayabilir.
bir başka yolu listeler için Arbitrary
örneği List a
[a]
izomorf olduğunu fark ve yeniden geçerli: sized
ile
instance Arbitrary a => Arbitrary (List a) where
arbitrary = toList <$> arbitrary
Teşekkür Zeta
Verilen oneOf' olacak 'o büyük olasılıkla listedeki tüm öğeler için aynı olasılıkları kullanır, boş olmayan bir liste elde etme şansı sadece% 50, bir öğeyle bir liste almak için yalnızca% 25, iki öğeyle bir liste almak için% 12,5 ve bu nedenle üzerinde. Bu tür bir davranış istiyorsanız (örn. Olasılık ** n ** ile bir uzunluk listesi oluşturun, 2 ** (-n + 1) 'dır, ancak bu genel olarak, bu kısa listelere yol açacaktır – Zeta
evet bu doğrudur ve çözümünüzün daha iyi olduğu ve zaten kabul gördüğünüz - bu yüzden bunu silmemi ister misiniz? – Carsten
Hayır, ama belki daha uzun olan listeleri oluşturmak için alternatif bir yol bulabilirsiniz.'toList :: [a] ->' [] a'ya izomorf olan türlerin bir örneği olarak a' ve 'keyfi 'toList <$>' seçeneğini listeleyin. – Zeta