如何在Applicatives上测试多态性函数?

dfe*_*uer 10 haskell quickcheck applicative

我刚写了一个函数(for Data.Sequence)

traverseWithIndex :: Applicative f => (Int -> a -> f b) -> Seq a -> f (Seq b)
Run Code Online (Sandbox Code Playgroud)

哪个应该服从

traverseWithIndex f = sequenceA . mapWithIndex f
Run Code Online (Sandbox Code Playgroud)

值得庆幸的是,这是一个直接的机械修改源mapWithIndex,所以我非常有信心它是正确的.但是,在更复杂的情况下,需要进行彻底的测试.我正在尝试编写一个QuickCheck属性来测试这个简单的属性.显然,我不能尝试每个Applicative仿函数!在测试幺半群时,使用某种类型的自由幺半群(即有限列表)进行测试是很有意义的.所以在这里用免费的applicative functor测试一些仿函数似乎是明智的.有两个困难:

  1. 如何选择合适的基础仿函数?我可能想要一个不适用或可穿越的讨厌或任何东西,但这样的事情似乎很难处理.

  2. 我如何比较结果?它们将具有功能,因此它们没有Eq实例.

Lui*_*las 2

\n

显然,我无法对每个Applicative函子都进行尝试!

\n
\n\n

我想起了这个博客文章系列,我不会声称完全理解:

\n\n\n\n

我记得从中吸取的教训是,你在野外看到的几乎每个应用函子都是这些更简单函子的组合、乘积或(受限)余积(并不意味着详尽无遗):

\n\n
    \n
  1. Const
  2. \n
  3. Identity
  4. \n
  5. (->)
  6. \n
\n\n

因此,虽然您无法对每个Applicative函子进行尝试,但您可以在 QuickCheck 属性中利用归纳参数,以确保您的函数适用于大型归纳定义的函子族。例如,您可以测试:

\n\n
    \n
  • 您的函数适用于您选择的“原子”应用程序;
  • \n
  • f如果您的函数对于函子和正确工作,那么它对于,和 也g正确工作。Compose f gProduct f gCoproduct f g
  • \n
\n\n
\n

我如何比较结果?它们里面有函数,所以它们没有Eq实例。

\n
\n\n

好吧,我想你可能需要看看函数相等性的 QuickCheck 测试。上次我不得不按照这些思路做一些事情时,我使用了 Conal 的checkers库,该库有一个EqProp,用于“可以通过随机抽样来测试相等性的值类型”。这应该已经给你一个想法\xe2\x80\x94即使你没有Eq函数的实例,QuickCheck也可能能够证明两个函数不相等。重要的是,这个实例存在:

\n\n
instance (Show a, Arbitrary a, EqProp b) => EqProp (a -> b)\n
Run Code Online (Sandbox Code Playgroud)\n\n

...并且任何具有Eq实例的类型都有一个简单的EqProp实例,其中(=-=) = (==).

\n\n

因此,在我看来,这表明使用Coyoneda Something作为基本函子,并弄清楚如何将所有小函数连接在一起。

\n