Haskell quickBatch testing: Applicative Monoid ZipList

北慕城南 提交于 2021-02-05 11:41:37

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!