2016-03-21 19 views
3

Aşağıdaki kod, denetleyicilerin geçiş yapılabilir sınamalarını sınar. Bunun nasıl düzeltileceğini değil, neden başarısız olduğunu açıklamak isterim.Bu örnek için Traversable örneği neden doğru değil?

λ> main 

traversable: 
    fmap: +++ OK, passed 500 tests. 
    foldMap: *** Failed! Falsifiable (after 6 tests): 
<function> 
Cons 4 (Cons (-2) (Cons (-5) (Cons 5 (Cons 2 Nil)))) 

cevap

5
instance Foldable List where 
    foldr f z (Cons x xs) = f x z 
    foldr _ z Nil = z 

Kişisel Katlanabilir örneği listenin kuyruk çapraz değildir:

import Test.QuickCheck 
import Test.QuickCheck.Checkers 
import Test.QuickCheck.Classes 

data List a = 
    Nil 
    | Cons a (List a) 
    deriving (Show, Eq, Ord) 

instance Functor List where 
    fmap _ Nil = Nil 
    fmap f (Cons x xs) = (Cons (f x) (fmap f xs)) 

instance Foldable List where 
    foldr f z (Cons x xs) = f x z 
    foldr _ z Nil = z 

instance Traversable List where 
    traverse f Nil = pure Nil 
    -- traverse f (Cons x Nil) = Cons <$> f x <*> pure Nil 
    traverse f (Cons x xs) = Cons <$> f x <*> (traverse f xs) 

instance Arbitrary a => Arbitrary (List a) where 
    arbitrary = sized go 
    where go 0 = pure Nil 
      go n = do 
      xs <- go (n - 1) 
      x <- arbitrary 
      return (Cons x xs) 

type TI = List 

instance Eq a => EqProp (List a) where (=-=) = eq 

main = do 
    let trigger = undefined :: TI (Int, Int, [Int]) 
    -- quickBatch (functor trigger) 
    quickBatch (traversable trigger) 

Burada o fmap yasaları değil, foldMap olanları geçtiğini görüyoruz.


checkers hep birlikte Functor ve Foldable test ederek Traversable örneklerini test: Bu Traversable sizin uygulanmasından foldMap ve fmap türemiştir ve foldMap ve tanımladığınız fmap aynı sonucu üretmek emin olun.

+0

Katlanabilir örneği nasıl yazarım? Bu bir 'b' değil' Liste b' yüzden elindeki 'foldr fz xs' By' foldr fz (Eksileri x xs) = Cons gibi bir şey (FXZ) (foldr fz xs) ' –

+0

@TheUnfunCat yazamaz beklediği bir' b ',' x 'ile birlestirildiginde, 'a' ve' b' türünde iki deger var, eğer bazi fonksiyonlar onlardan yeni bir 'b' üretiyorsa ...? – zakyggaps

+0

Const düşünebildiğim tek şey ... Uygulamacı ya da whatevz sınıfında bazıları olabilir ama ben de güldüm. –

İlgili konular