我正在为我编写的二进制搜索函数编写测试。
module Tests where
import Data.List (sort)
import Test.QuickCheck
import BinarySearch (binarySearch)
prop_equals_elem x xs = (binarySearch x $ sort xs) == (x `elem` xs)
args = Args {replay = Nothing, maxSuccess = 200, maxDiscard=200, maxSize=200, chatty = False}
main = do
quickCheck (prop_equals_elem :: (Ord a) => a -> [a] -> Bool)
Run Code Online (Sandbox Code Playgroud)
在 ghci 中使用 quickCheck 效果很好,但是当我尝试运行 main 时,它给出了错误
Tests.hs:12:5:
Ambiguous type variable `a0' in the constraints:
(Arbitrary a0) arising from a use of `quickCheckWith'
at Tests.hs:12:5-18
(Show a0) …Run Code Online (Sandbox Code Playgroud) 假设我有一个名为 的 Haskell 模块Foo,在src/Foo.hs. 还假设Foo导出一个类型Bar。
现在我想为Bar(Foo实际上是整个模块)编写单元测试,所以我将几个 QuickCheck 属性放入test/FooTest.hs; 但是,嘿,现在我需要Arbitrary为Bar.
还有一个问题:在-Wall -Werror模式中,ghc需要实例声明出现在两个地方之一:在定义类型的同一个文件中,或者在定义类的地方。但我不想让我的Foo模块与 QuickCheck 的构建依赖关系混乱,而且我显然无法Bar向 QuickCheck添加实例。
那么如何使我的数据类型成为 的实例Arbitrary,仅用于单元测试,而不为我的模块的用户引入对 QuickCheck 的依赖,并且不会抛出-Wall -Werror窗口?
我试图为身份编写一个 QuickCheck 测试
f $ y = f y
Run Code Online (Sandbox Code Playgroud)
我最初的计划是编写一个返回函数和整数的任意生成器,具有签名Gen (Int -> Int, Int)
并且在prop_DollerDoesNothing测试中,带/不带函数应用程序$给出相同的结果。
这是我的代码:
prop_DollarDoesNothing :: Property
prop_DollarDoesNothing =
forAll arbitraryFuncInt (\(f, y) -> (f $ y) == (f y))
arbitraryFuncInt :: Gen (Int -> Int, Int)
arbitraryFuncInt = do
f <- elements [(\x -> x*2), (\x -> x+3), (\x -> x-2)]
y <- arbitrary :: Gen Int
return (f, y)
Run Code Online (Sandbox Code Playgroud)
它生成了以下有用的错误消息:
* No instance for (Show (Int -> Int))
arising from a …Run Code Online (Sandbox Code Playgroud) newtype Cont k a = Cont { runCont :: (a -> k) -> k }
instance Functor (Cont k) where
-- fmap :: (a -> b) -> (Cont k a) -> (Cont k b)
fmap f (Cont akTok) = Cont $ ???
Run Code Online (Sandbox Code Playgroud)
我的疑惑:
我们只能将 Functor 实例写入任何可以产生类型输出的数据类型(例如:[a], Maybe a, (y -> a)),但不能用于消耗类型的数据类型。现在,在上述数据键入它消耗了功能消耗一个那么这如何间接消耗的可视为生产型一个。这意味着我们不能为(k -> a) -> k编写 Functor 实例?
如何读取Cont数据类型。续产生ķ时,它有一个?(就像 Javascript XHR 回调在从服务器获取数据时生成 JSON 一样?)
如何为Cont数据类型编写 …
我推出了自己的elem函数,称为elem'
elem' :: (Eq a) => a -> [a] -> Bool
elem' n ys = foldl (\acc p -> if (p == n) then True else False) False ys
Run Code Online (Sandbox Code Playgroud)
似乎有效,但我想在 GHCi 中快速检查它,所以我 import Test.QuickCheck
verboseCheck (\a -> (\xs ->( (elem' a xs) == (elem a xs)) ) )
Run Code Online (Sandbox Code Playgroud)
在测试函数上没有类型声明它测试正常,但那是因为它只测试空输入。
我的测试函数类型声明有问题:
verboseCheck (\a->(\xs->((elem' a xs)==(elem a xs))) :: Int->[Int]->Bool)
verboseCheck (\a->(\xs->((elem' a xs)==(elem a xs))) :: Char->[Char]->Bool)
Run Code Online (Sandbox Code Playgroud)
第一个错误:
• Couldn't match expected type ‘[Int] -> Bool’
with actual …Run Code Online (Sandbox Code Playgroud) 我在我的程序中使用Data.List.Vector,现在我想使用quickCheck.但是,没有这方面的例子.因为[Double]已经有任意,我想我可以做类似的事情
instance Arbitrary V.Vector Double where
arbitrary = V.fromList (arbitrary :: [Double])
Run Code Online (Sandbox Code Playgroud)
唉,GHC完全不喜欢这个:
`Arbitrary' is applied to too many type arguments
In the instance declaration for `Arbitrary V.Vector Double'
Run Code Online (Sandbox Code Playgroud)
我想我也可以制作一堆接受[Double]并使用V.fromList的属性,但这看起来很单调乏味.
是否有一个修饰符允许我生成一个不包含指定整数的整数列表?
这是一个完成相同工作的功能:
listofInts :: Int -> Gen [Integer]
listofInts a = rmInt a [] arbitrary
rmInt :: Int -> [Int] -> [Int] -> [Int]
rmInt a newList [] = newList
rmInt a newList (x:xs)
|a == x = newList : rmInt a xs
|otherwise = newList : x : rmInt a xs
Run Code Online (Sandbox Code Playgroud) 上下文
我有以下功能:
prop_SignAndVerify :: (PrivKey a b) => Blind a -> BS.ByteString -> Bool
prop_SignAndVerify bsk msg = case verify pk msg sig of
Left e -> error e
Right b -> b
where
sk = getBlind bsk
pk = toPublic sk
sig = case sign sk msg of
Left e -> error e
Right s -> s
Run Code Online (Sandbox Code Playgroud)
我想做的事情如下:
-- instance PrivKey RSA.PrivateKey RSA.PublicKey where...
genRSA :: Gen RSA.PrivateKey
genRSAMessage :: Gen BS.ByteString
main = do
quickCheck . verbose
$ …Run Code Online (Sandbox Code Playgroud) 这是一个hack(cogsRpm用户提供的函数,应该匹配go的输出):
propCheck ns = cogsRpm (ns ++ [42]) == go (ns ++ [42])
Run Code Online (Sandbox Code Playgroud)
我添加了42来停止生成零长度列表的快速检查.它也可能会失败,因为它也不应该在那里有零.
我阅读了文档,但是没有足够的例子来解析如何实际使用它们.我确实设法在另一个案例中得到这个:
prop_check (Positive x) (Positive y) = updateHealth x y == if y > x then 0 else x-y
Run Code Online (Sandbox Code Playgroud)
这迫使阳性,我试图结合了一堆东西来获得listOf1和NonZero,但我无法找出语法,因此黑客将元素添加到列表中.我该如何避免这种黑客攻击?