2016-03-21 5 views

答えて

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

あなたの折り畳み式のインスタンスは、リストの末尾を横断していません:

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) 

ここでは、それがfmapの法律ではなく、foldMapものを渡していることがわかります。


checkersはすべて一緒FunctorFoldableをテストすることによって、あなたのTraversableインスタンスをテスト:それはTraversableの実装からfoldMapfmapを導出し、彼らはあなたが定義されfoldMapfmapと同じ結果を生み出すことを確認してください。

+0

しかし、折り畳み可能なインスタンスを作成するにはどうすればよいですか?それは 'リストb'ではないと期待しているので、 'foldr fz(Cons x xs)= Cons(fxz)(foldr fz xs)'のように書くことはできません。 –

+0

@TheUnfunCat 'foldr fz xs'によって、 'b'と' x'を組み合わせると、 'a'と' b'の2つの値があります。 – zakyggaps

+0

Constは私が考えることができる唯一のものです... Applicativeかwhatevzのためにクラスにいくつかあるかもしれませんが、私は困惑しています。 –

関連する問題