如何解决为复杂类型创建任意实例
我正在尝试使用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
是否可以像我一样在做注释符号中使用where
?
解决方法
如果您已经拥有复杂类型的所有构成类型的Arbitrary
实例(在这种情况下为Date
,Activity
等),则无需做很多事情
由于列表,元组等的内置Arbitrary
实例,您可以像这样简单地定义组成的Arbitrary
实例:
instance Arbitrary Schedule where
arbitrary = Schedule <$> arbitrary
编译器查看Schedule
数据构造函数,其类型为[(Date,[Activity])] -> Schedule
。然后,推断出右手arbitrary
必须具有类型Gen (Date,[Activity])
,即元组。 Arbitrary
是否存在(a,b)
实例?
是的,它确实:(Arbitrary a,Arbitrary b) => Arbitrary (a,b)
。如果a
是Arbitrary
实例,并且b
是,则存在。
在这种情况下,a ~ Date
,您已经为此定义了一个自定义实例。第二个元组元素稍微复杂一点,因为它是b ~ [Activity]
。 Arbitrary
是否有一个[Activity]
实例?
是,再次内置:Arbitrary a => Arbitrary [a]
。如果元素类型具有实例,则列表具有Arbitrary
实例,并且同样存在Activity
的自定义实例。
似乎您正在明确地试图限制生成值的大小。您可以使用resize函数来代替显式地执行此操作。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。