为复杂类型制作任意实例
making an Arbitrary instance for a complicated type
我正在尝试使用 QuickCheck 检查我的代码,因此我需要为我的类型创建 Arbitrary
个实例。一种data Schedule
复杂,不知如何正确对待。三个实例(Date
、Activity
、TimeStart
)工作正常。但是最后一个例子(Schedule
)是不正确的,我寻求帮助来修复它。
data Schedule = Schedule [(Date,[Activity])]
data Date = Date Year Month Day
data Activity = Activity (ActivityName,TimeStart)
data TimeStart = TimeStart Hour Minute
type Year = Integer
type Month = Integer
type Day = Integer
type ActivityName = String
type Hour = Integer
type Minute = Integer
instance Arbitrary Date where
arbitrary = do
year <- choose (2000, 2050)
month <- choose (1, 12)
day <- choose (1, 28)
return $ Date year month day
instance Arbitrary Activity where
arbitrary = do
size <- choose (5, 15 :: Integer)
activityName <- sequence [elements ['a'..'z'] | _ <- [1..size]]
timeStart <- arbitrary
return $ Activity (activityName, timeStart)
instance Arbitrary TimeStart where
arbitrary = do
hour <- choose (1, 24)
minute <- choose (1, 60)
return $ TimeStart hour minute
instance Arbitrary Schedule where
arbitrary = do
size <- choose (5, 50 :: Integer)
schedule <- sequence [(arbitrary, arbitraryActivity) | _ <- [1..size]]
return $ Schedule schedule where
arbitraryActivity = do
size <- choose (5, 50 :: Integer)
activityName <- sequence [arbitrary | _ <- [1..size]]
return $ ActivityName activityname
第一个错误在这一行:schedule <- sequence [(arbitrary, arbitraryActivity) | _ <- [1..size]]
Expected type: Gen [Gen b0] Actual type: (Gen a0, [Gen b0])
但是如何为这样的结构做一个任意[(x,y)]
?
第二个错误在最后一行:return $ ActivityName activityname
Data constructor not in scope: ActivityName
是否不允许像我那样在 do-notation 中使用 where
?
如果复杂类型的所有组成类型已经有 Arbitrary
个实例(在本例中为 Date
、Activity
等),则不必做很多。
由于 built-in Arbitrary
列表、元组等实例,您可以像这样简单地定义组合 Arbitrary
实例:
instance Arbitrary Schedule where
arbitrary = Schedule <$> arbitrary
编译器查看 Schedule
数据构造函数,其类型为 [(Date, [Activity])] -> Schedule
。然后,它推断 right-hand arbitrary
必须具有 Gen (Date, [Activity])
类型,即元组。 (a, b)
是否存在 Arbitrary
实例?
是的,确实如此:(Arbitrary a, Arbitrary b) => Arbitrary (a, b)
。如果 a
是一个 Arbitrary
实例,并且如果 b
是。
在本例中,a ~ Date
,并且您已经为其定义了一个自定义实例。第二个元组元素有点复杂,因为它是 b ~ [Activity]
。 [Activity]
是否有 Arbitrary
实例?
是的,又是 built-in:Arbitrary a => Arbitrary [a]
。如果元素类型有实例,则列表有 Arbitrary
个实例,同样,Activity
.
存在自定义实例
您似乎在明确尝试限制生成值的大小。您可以使用 resize 函数,而不是明确地执行此操作。
我正在尝试使用 QuickCheck 检查我的代码,因此我需要为我的类型创建 Arbitrary
个实例。一种data Schedule
复杂,不知如何正确对待。三个实例(Date
、Activity
、TimeStart
)工作正常。但是最后一个例子(Schedule
)是不正确的,我寻求帮助来修复它。
data Schedule = Schedule [(Date,[Activity])]
data Date = Date Year Month Day
data Activity = Activity (ActivityName,TimeStart)
data TimeStart = TimeStart Hour Minute
type Year = Integer
type Month = Integer
type Day = Integer
type ActivityName = String
type Hour = Integer
type Minute = Integer
instance Arbitrary Date where
arbitrary = do
year <- choose (2000, 2050)
month <- choose (1, 12)
day <- choose (1, 28)
return $ Date year month day
instance Arbitrary Activity where
arbitrary = do
size <- choose (5, 15 :: Integer)
activityName <- sequence [elements ['a'..'z'] | _ <- [1..size]]
timeStart <- arbitrary
return $ Activity (activityName, timeStart)
instance Arbitrary TimeStart where
arbitrary = do
hour <- choose (1, 24)
minute <- choose (1, 60)
return $ TimeStart hour minute
instance Arbitrary Schedule where
arbitrary = do
size <- choose (5, 50 :: Integer)
schedule <- sequence [(arbitrary, arbitraryActivity) | _ <- [1..size]]
return $ Schedule schedule where
arbitraryActivity = do
size <- choose (5, 50 :: Integer)
activityName <- sequence [arbitrary | _ <- [1..size]]
return $ ActivityName activityname
第一个错误在这一行:schedule <- sequence [(arbitrary, arbitraryActivity) | _ <- [1..size]]
Expected type: Gen [Gen b0] Actual type: (Gen a0, [Gen b0])
但是如何为这样的结构做一个任意[(x,y)]
?
第二个错误在最后一行:return $ ActivityName activityname
Data constructor not in scope: ActivityName
是否不允许像我那样在 do-notation 中使用 where
?
如果复杂类型的所有组成类型已经有 Arbitrary
个实例(在本例中为 Date
、Activity
等),则不必做很多。
由于 built-in Arbitrary
列表、元组等实例,您可以像这样简单地定义组合 Arbitrary
实例:
instance Arbitrary Schedule where
arbitrary = Schedule <$> arbitrary
编译器查看 Schedule
数据构造函数,其类型为 [(Date, [Activity])] -> Schedule
。然后,它推断 right-hand arbitrary
必须具有 Gen (Date, [Activity])
类型,即元组。 (a, b)
是否存在 Arbitrary
实例?
是的,确实如此:(Arbitrary a, Arbitrary b) => Arbitrary (a, b)
。如果 a
是一个 Arbitrary
实例,并且如果 b
是。
在本例中,a ~ Date
,并且您已经为其定义了一个自定义实例。第二个元组元素有点复杂,因为它是 b ~ [Activity]
。 [Activity]
是否有 Arbitrary
实例?
是的,又是 built-in:Arbitrary a => Arbitrary [a]
。如果元素类型有实例,则列表有 Arbitrary
个实例,同样,Activity
.
您似乎在明确尝试限制生成值的大小。您可以使用 resize 函数,而不是明确地执行此操作。