gpt4 book ai didi

Haskell 高阶类型的任意实例

转载 作者:行者123 更新时间:2023-12-02 15:55:29 26 4
gpt4 key购买 nike

我有这个类型,它是 SemiGroup 的一个实例。我想写一个quickCheck方法来确保它是正确的。如何创建这种类型的任意实例?

newtype Combine a b =
Combine { unCombine :: a -> b }

instance Semigroup b => Semigroup (Combine a b) where
x <> y = Combine $ \n -> unCombine x n <> unCombine y n

instance (Q.Arbitrary a, Num a) => Q.Arbitrary (Combine a b) where
arbitrary = do
a <- Q.arbitrary
return $ Combine (\n -> Sum(n+1)) a

最佳答案

最小的修复方法是打开FlexibleInstances并写入:

instance (Q.Arbitrary a, Num a) => Q.Arbitrary (Combine a (Sum a)) where
arbitrary = do
a <- Q.arbitrary :: Q.Gen ()
return $ Combine (\n -> Sum(n+1))

但是,这有点令人不满意:我观察到 a 完全未使用(因此必须手动给出类型签名!),并且函数的分布有点无聊,因为它返回函数 (+1)(直到新类型包装),概率为 1。(也许您想要 return $ Couple (\n -> Sum (n+a)) ?但即便如此,您可以通过这种方式生成的函数类还是有点无聊。我不确定您的真正意思,而且我不会花很长时间推测。)

如果你想做得正确,你应该为每个输入生成一个随机输出。这对于 universe 来说非常方便。封装:

import Data.Universe
import Data.Universe.Instances.Reverse
instance (Ord a, Finite a, Q.Arbitrary b) => Q.Arbitrary (Combine a b) where
arbitrary = Combine <$> sequenceA (const Q.arbitrary)

作为一个附带好处,这不需要任何扩展。但是,您应该小心选择具有小域的输入类型 - Combine Bool (Sum Int) 应该没问题,甚至 Combine Word8 (Sum Word8),但如果如果你尝试测试像 Combine Int (Sum Int) 这样的类型的属性,你会后悔的!

关于Haskell 高阶类型的任意实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33642741/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com