Ho visto occasionalmente persone dire che il tipo Gen in QuickCheck non obbedisce alle leggi della monade, anche se non ho visto molte spiegazioni per seguirlo. Ora, il modulo Test.QuickCheck.Gen.Unsafe di QuickCheck 2.7 dice che Gen è solo "moralmente" una monade, ma la breve spiegazione mi lascia grattarmi la testa. Puoi fare un esempio passo passo di come Gen rompe le leggi della monade?QuickCheck Gen non è una monade
risposta
Se vuoi dimostrare che qualcosa è una monade, devi dimostrare che soddisfa le leggi della monade. Ecco uno
m >>= return = m
La documentazione per Gen
si riferisce a ciò che il (=)
in quella legge significa in realtà. I valori Gen
sono funzioni, quindi è difficile confrontarli per l'uguaglianza. Invece, potremmo inline le definizioni di (>>=)
e return
e dimostrare attraverso il ragionamento equazionale che la legge vale
m = m >>= return
m = m >>= (\a -> MkGen (\_ _ -> a))
MkGen m = MkGen m >>= (\a -> MkGen (\_ _ -> a))
MkGen m = MkGen (\r n ->
let (r1,r2) = split r
MkGen m' = (\a -> MkGen (\_ _ -> a)) (m r1 n)
in m' r2 n
)
MkGen m = MkGen (\r n ->
let (r1,r2) = split r
MkGen m' = MkGen (\_ _ -> m r1 n)
in m' r2 n
)
MkGen m = MkGen (\r n ->
let (r1,r2) = split r
in (\_ _ -> m r1 n) r2 n
)
MkGen m = MkGen (\r n ->
let (r1,r2) = split r
in m r1 n
)
MkGen m = MkGen (\r -> m (fst $ split r))
Quindi, in definitiva, la legge Monade sembra non riuscire a tenere a meno che fst . split == id
, which is doesn't. E non dovrebbe
Ma moralmente, è fst (split r)
lo stesso di r
? Bene, a patto che stiamo operando come se ignorassimo il valore iniziale, sì, fst . split
è moralmente equivalente a id
. I valori effettivi prodotti da Gen
-as-a-function variano, ma la distribuzione dei valori è invariabile.
E questo è ciò a cui si riferisce la documentazione. La nostra eguaglianza nelle leggi della monade non regge in modo equo, ma solo "moralmente" considerando Gen a
una distribuzione di probabilità su valori di a
.
- 1. Perché Scalas non è una monade?
- 2. Non è una monade, ma che cos'è?
- 3. QuickCheck: come combinare due generatori?
- 4. Quando fa esattamente gen 0, gen 1, gen 2?
- 5. Come posso testare una funzione di ordine superiore usando QuickCheck?
- 6. Quickcheck per test non booleani
- 7. Perché Scala non ha una Monade IO?
- 8. Ricorsione in una monade
- 9. Ogni monade è monoide?
- 10. Haskell: Monade di monade
- 11. Trova il valore che non è riuscito per quickcheck
- 12. Utilizzo di una monade all'interno della monade IO
- 13. Qual è la differenza tra una monade e una chiusura?
- 14. mappe Haskell ritorno una monade
- 15. proprietà condizionale QuickCheck
- 16. Eclipse Android gen esiste già ma non è una cartella sorgente
- 17. QuickCheck 2 elaborazione batch
- 18. Haskell Cabal QuickCheck Integration
- 19. Perché la monade dello stato non è attraversabile?
- 20. QuickCheck per Javascript
- 21. Utilizzo di quickCheck
- 22. Novità di QuickCheck 2?
- 23. verboseCheck in QuickCheck 2?
- 24. Perché free non è monade esempio nel Scalaz 7.1.5?
- 25. Perché le monade non compongono in scala
- 26. Monade di Haskell contro Monade di APL
- 27. Scala IO monade: qual è il punto?
- 28. esempio MonadTransControl per una monade personalizzato
- 29. annotazione codice Gen con JavaPoet
- 30. scegliere una monade in fase di esecuzione
Codifica le leggi monade per 'Gen' come proprietà quickcheck, in esecuzione con lo stesso seme e lascia che quickcheck trovi i tuoi controesempi. :-) – luqui