问题
I'm trying to do a quickBatch test on the solution provided at ZipList Monoid haskell. I'll need some advice as to how to continue from here or should I try something else for EqProp (Ap f a)? How do I go about deriving a solution for this?
newtype Ap f a = Ap { getAp :: f a }
deriving (Eq, Show)
instance (Applicative f, Semigroup a) =>
Semigroup (Ap f a) where
Ap xs <> Ap ys =
Ap $ liftA2 (<>) xs ys
instance (Applicative f, Monoid a) =>
Monoid (Ap f a) where
mempty = Ap $ pure mempty
Ap xs `mappend` Ap ys =
Ap $ liftA2 mappend xs ys
app :: Ap ZipList (Sum Int)
app = Ap (ZipList [1,2 :: Sum Int])
test :: Ap ZipList (Sum Int)
test = app <> app
instance Arbitrary (f a) =>
Arbitrary (Ap f a) where
arbitrary = Ap <$> arbitrary
instance Eq a => EqProp (Ap f a) where
xs =-= ys = xs' `eq` ys' where
xs' =
let (Ap l) = xs
in take 3000 l
ys' =
let (Ap l) = ys
in take 3000 l
main :: IO ()
main = do
quickBatch $ monoid app
There are 2 similar error messages for this code, each for the 2 lines:
in take 3000 l
Error message:
Couldn't match type ‘f’ with ‘[]’
‘f’ is a rigid type variable bound by
the instance declaration at Line of Code
Expected type: [a]
Actual type: f a
In the second argument of ‘take’, namely ‘l’
In the expression: take 3000 l
回答1:
The problem is that you say
instance Eq a => EqProp (Ap f a)
but then in the instance you use take, which works only for lists and not arbitrary type constructors f. For testing purposes, it would be reasonable to just limit the instance with either
instance Eq a => EqProp (Ap ZipList a)
or
instance (Eq a, f ~ ZipList) => EqProp (Ap f a)
You'll still need to unwrap the ZipLists. Either of these will require additional language extensions; just do what the error messages say. Outside of testing, it's usually better practice to use a newtype wrapper: something like
{-# language GeneralizedNewtypeDeriving, DeriveTraversable #-}
newtype MonZipList a = MonZipList (Ap ZipList a)
deriving (Applicative, Alternative, Semigroup
, Monoid, Functor, Foldable, Traversable, ...)
来源:https://stackoverflow.com/questions/65752398/haskell-quickbatch-testing-applicative-monoid-ziplist