我想使用SmallCheck来测试我的代码。我成功地生成了一对ints的任意列表,但这不是我的类型应该包含的内容。该列表表示一组范围,其中[1,3),[4,6)将被编码/存储为[(1,3),(4,6)]。
这些是我的范围的规范化形式的不变量:
fst a < snd a
snd a < fst b where a is before b in the list我想要将这一点传递给SmallCheck,这样它就不会产生大量我丢弃的值,因为它们不能满足我的不变量,但也许这是不可能的。
如何生成满足不变量的列表?
发布于 2016-04-05 17:51:10
偏爱特定于应用程序的类型而不是构建的Int类型(Int,List)。这不仅是对SmallCheck的建议,也是对任何语言的软件的建议。
data Interval = Interval (Int,Int)
data Domain = Domain [Interval]编写执行不变量的智能构造函数。
interval :: Int -> Int -> Interval
interval x y = Interval (min x y, max x y) -- if you want this
domain :: [Interval] -> Domain
domain ints = Domain ... (something that sorts intervals, and perhaps merges them)然后使用这些来创建Serial实例。
发布于 2016-04-05 21:24:00
我同意用用户定义的类型更好地解决这个问题。
我假设您正在编写一种算法,该算法具有某些属性,用于按升序排序的不相交的半开间隔,然后提供Serial实例。
我决定给Interval和AscDisjIntervals不同的生成器,而不是按另一个实现。
正如我在评论中所写的,AscDisjIntervals的算法是
Integer的列表(这是为了避免Int溢出)Intervals.hs
{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses #-}
module Intervals where
newtype Interval = I (Integer,Integer) deriving(Eq)
instance Show Interval where
show (I (a,b)) = "["++show a ++ ", "++ show b ++ "]"
instance Monad m => Serial m Interval where
series = let a_b a b = I (getNonNegative $ min a b , getNonNegative $ max a b)
in cons2 a_b
newtype AscDisjIntervals = ADI [Interval] deriving (Eq)
instance Show AscDisjIntervals where
show (ADI x) = "|- "++ (unwords $ map show x) ++ " ->"
instance Monad m => Serial m AscDisjIntervals where
series = cons1 aux1
aux1 :: [NonNegative Int] -> AscDisjIntervals
aux1 xx = ADI . generator . tail $ scanl (+) 0 xx
where generator [] = []
generator (_:[]) = []
generator (x:y:xs) = let i = I (getNonNegative x ,getNonNegative y)
in i:generator xs注意:我只编译了程序,没有测试任何属性。
https://stackoverflow.com/questions/36426303
复制相似问题