首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SmallCheck:类型化串行的类型实例

SmallCheck:类型化串行的类型实例
EN

Stack Overflow用户
提问于 2013-12-14 08:27:44
回答 1查看 259关注 0票数 2

我正试图找出如何结合使用基于smallcheck属性的测试库。

我遇到了多字段记录类型的问题:如何使用Serial类型的mor超过4个字段成员来创建记录类型?

我认为这是正常的做法:

代码语言:javascript
复制
{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses #-}

import Test.Tasty
import Test.Tasty.SmallCheck
import Test.SmallCheck.Series

data T1 = T1 { p1 :: Int,
               p2 :: Char,
               p3 :: [Int]
             } deriving (Show, Eq)

instance (Monad m) => Serial m T1 where
    series = cons3 T1 

main :: IO ()
main = defaultMain tests

tests :: TestTree
tests = testGroup "Tests" [scProps]

scProps = testGroup "(checked by SmallCheck)"
  [ testProperty "Test1" prop_test1 
  ]

prop_test1 x y = x == y
               where types = (x :: T1, y :: T1)

这是可行的,当然'Test1‘失败了。但是,这种方法不适用于超过4个字段的记录类型,因为consN函数仅定义为最多接受4个参数。下面是声明函数的模块链接Test.SmallCheck.Series

例如:

代码语言:javascript
复制
data T1 = T1 { p1 :: Int,
               p2 :: Char,
               p3 :: Int,
               p4 :: Int,
               p5 :: [Int]
             } deriving (Show, Eq)

将它添加到Serial的方法是什么?我试过像这样使用泛型:

代码语言:javascript
复制
{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses #-}
{-# LANGUAGE DeriveGeneric #-}

import Test.Tasty
import Test.Tasty.SmallCheck
import Test.SmallCheck.Series
import GHC.Generics

data T1 = T1 { p1 :: Int,
               p2 :: Char,
               p3 :: [Int]
             } deriving (Show, Generic)

instance Serial m a => Serial m T1

但ghc拒绝接受上述示例,并提供以下信息:

代码语言:javascript
复制
Variable occurs more often in a constraint than in the instance head
  in the constraint: Serial m a
  (Use -XUndecidableInstances to permit this)
  In the instance declaration for `Serial m T1'

事先非常感谢!

jules

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-12-14 09:37:14

例如,cons3是如何在SmallCheck中定义的:

代码语言:javascript
复制
cons3 :: (Serial m a, Serial m b, Serial m c) =>
         (a->b->c->d) -> Series m d
cons3 f = decDepth $
  f <$> series
    <~> series
    <~> series

因此,通过类推,下面是如何用任意数量的字段定义类型的实例:

代码语言:javascript
复制
instance Monad m => Serial m T1 where
  series = decDepth $
    T1 <$> series <~> series <~> series <~> series <~> series

(上述定义中的每个series都对应于数据结构的一个字段)。

关于泛型代码,应该如下所示:

代码语言:javascript
复制
 instance Monad m => Serial m T1

这里没有a,所以您的约束是多余的(实际上会导致问题)。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20581177

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档