haskell - 如何为包装函数的类型编写任意实例?

标签 haskell quickcheck

我有这种包装函数的类型

newtype Transaction d e r = Transaction (d -> Either e (d,r))

...我想对其 Functor 和 Applicative 实例进行快速检查测试,但编译器提示它没有 Arbitrary 实例。

我尝试这样做,但我一直坚持生成随机函数。

谢谢!

== 更新 ==

快速检查属性是这样定义的

type IdProperty f a = f a -> Bool
functorIdProp :: (Functor f, Eq (f a)) => IdProperty f a
functorIdProp x = (fmap id x) == id x

type CompositionProperty f a b c = f a -> Fun a b -> Fun b c -> Bool
functorCompProp :: (Functor f, Eq (f c)) => CompositionProperty f a b c
functorCompProp x (apply -> f) (apply -> g) = (fmap (g . f) x) == (fmap g . fmap f $ x)

instance (Arbitrary ((->) d  (Either e (d, a)))) => Arbitrary (DbTr d e a) where
    arbitrary = do
      f <- ...???
      return $ Transaction f

...测试看起来像这样:

spec = do
  describe "Functor properties for (Transaction Int String)" $ do
    it "IdProperty (Transaction Int String) Int" $ do
      property (functorIdProp :: IdProperty (Transaction Int String) Int)

    it "CompositionProperty (Transaction Int String) Int String Float" $ do
      property (functorCompProp :: CompositionProperty (Transaction Int String) Int String Float)

最佳答案

你应该使用 Test.QuickCheck.Function包装器来测试功能。如果您只需要为您的 Transaction 测试类型类规则,那么为 Transaction 使用 ArbitraryCoArbitrary 实例似乎没有任何意义 类型(但如果你真的需要它,你可以找到 my answer to this question )。

要测试定律,您可以按如下方式编写属性:

{-# LANGUAGE DeriveFunctor #-}

import Test.QuickCheck
import Test.QuickCheck.Function

newtype Transaction d e r = Transaction (d -> Either e (d,r))
  deriving (Functor)

-- fmap id ≡ id
prop_transactionFunctorId :: Int
                          -> Fun Int (Either Bool (Int,String)) 
                          -> Bool
prop_transactionFunctorId d (Fun _ f) = let t              = Transaction f
                                            Transaction f' = fmap id t
                                        in f' d == f d

好吧,这可能看起来不像您想要的那么漂亮。但这是测试任意函数的好方法。例如,我们可以将最后一行 in f' d == f d 替换为 in f' d == f 1 以查看失败时如何失败:

ghci> quickCheck prop_transactionFunctorId 
*** Failed! Falsifiable (after 2 tests and 4 shrinks):    
0
{0->Left False, _->Right (0,"")}

关于haskell - 如何为包装函数的类型编写任意实例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44132084/

相关文章:

haskell - Semigroupoid 和 Semigroup 类之间的关系

haskell - 使用镜头访问不存在的字段时如何避免默认返回值?

python - haskell 与 python 打字

haskell - 自动收集所有快速检查

haskell - 具有持续集成的 HUnit/QuickCheck

haskell - 是否有用于更新嵌套数据结构的 Haskell 习惯用法?

haskell - 为什么 GHCi 在此实例声明中报告 "A constraint must be a monotype"?

javascript - 快速检查 Javascript

java - 你在实际项目中使用过 Quickcheck

r - 测试软件QuickCheck有R接口(interface)吗?