简体   繁体   中英

Haskell quickBatch testing: Applicative Monoid ZipList

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 fa) ? 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

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 ZipList s. 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, ...)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM