简体   繁体   English

Haskell 快速批量测试:Applicative Monoid ZipList

[英]Haskell quickBatch testing: Applicative Monoid ZipList

I'm trying to do a quickBatch test on the solution provided at ZipList Monoid haskell .我正在尝试对quickBatch Monoid haskell提供的解决方案进行快速批处理测试。 I'll need some advice as to how to continue from here or should I try something else for EqProp (Ap fa) ?我需要一些关于如何从这里继续的建议,还是应该为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此代码有 2 条类似的错误消息,每条有 2 行: 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 .但是在您使用take的实例中,它仅适用于列表而不适用于任意类型的构造函数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.您仍然需要解开ZipList的包装。 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, ...)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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