如何使用检查器库

时间:2017-11-19 12:57:32

标签: haskell quickcheck

如何使用checkers库来测试简单解析器的Functor定律?

import Test.QuickCheck
import Test.QuickCheck.Checkers
import Test.QuickCheck.Classes
import qualified Data.ByteString as BS

type Index = Int

newtype Parser a = Parser (BS.ByteString -> Index -> (a, Index))

runParser :: Parser a -> BS.ByteString -> Index -> (a, Index)
runParser (Parser p) = p

instance Functor Parser where
    f `fmap` p = Parser $  \bs i -> 
      let (a, ix) = runParser p bs i
      in (f a, ix)

我想我必须使用Test.QuickCheck.Classes

中的仿函数函数

类型是:

functor :: forall m a b c. (Functor m, Arbitrary a, Arbitrary b, Arbitrary c, 
           CoArbitrary a, CoArbitrary b, Show (m a), Arbitrary (m a), EqProp (m a), EqProp (m c)) 
           => m (a, b, c) -> TestBatch

现在 m 应该是我的Functor Parser ,所以我需要像

这样的东西
main :: IO ()
main = = quickBatch (functor (Parser (a, b, c))

但是我对(a, b, c)使用了什么?

注意:我知道快速QuickTest测试不是证据,我已经阅读了讨论 How do I test this applicative instance with checkers? (No instance for CoArbitrary (Validation e0 [Char]))。 但是,如果快速测试失败,我知道我的Functor实例已损坏......

修改

我取得了一些进展:我可以写

main :: IO ()
main = quickBatch $ functor (undefined :: Parser (Int, String, Char))

这会产生错误:没有(Show(Parser Int))的实例

仿函数的类型签名中,没有提到 Read 实例, 所以我可以写

instance Show (Parser a) where
   show (Parser a) = "Parsers cannot be printed"

这会产生一个新错误:

• No instance for (Arbitrary (Parser Int))
    arising from a use of ‘functor’
• In the second argument of ‘($)’, namely

我猜这是一个更棘手的问题......

0 个答案:

没有答案