gpt4 book ai didi

haskell - TimeOfDay 的任意实例

转载 作者:行者123 更新时间:2023-12-02 17:08:04 26 4
gpt4 key购买 nike

使用 QuickCheck,我想创建一系列伪随机数 TimeOfDay值。

创建特定的TimeOfDay很容易:

now = TimeOfDay 17 35 22

使用 GHCi 8.6.5 打印此结果:

17:35:22

我认为使用 QuickCheck 创建 TimeOfDay 值所需的 Arbitrary 实例将是:

instance Arbitrary TimeOfDay where
arbitrary = do
hour <- elements [0 .. 23]
min <- elements [0 .. 59]
-- Going till 60 accounts for leap seconds
sec <- elements [0 .. 60]
return $ TimeOfDay hour min sec

尽管进行了类型检查,但运行以下行会挂起 GHCi,并在几秒钟后将 Killed 写入控制台:

sample (arbitrary :: Gen TimeOfDay)

问题在哪里?

最佳答案

正如您所发现的,todSeconds 的类型为 Pico这是一个分辨率为 10-12 的定点数,因此这意味着 [0 .. 60] 6×1013+1 值。迭代整个列表很容易需要大约 1000 秒。

话虽如此,您首先不需要在此处使用 elements 。我们可以使用choose :: Random a => (a, a) -> Gen a这将生成一个范围内的随机值(包括两个范围)。

然后我们可以将Arbitrary定义为:

instance Arbitrary TimeOfDay where
arbitrary = TimeOfDay
<$> choose (0, 23)
<*> choose (0, 59)
<*> (fmap MkFixed (choose (0, 61*10^12-1)))

这给了我们:

Main> sample (arbitrary :: Gen TimeOfDay)
15:45:04.132804129488
11:06:12.447614162981
12:07:50.773642440667
04:40:47.966398431784
02:30:09.60931551059
00:51:46.564756092467
07:57:44.170698241052
02:45:57.743854623407
00:17:22.627238967351
13:03:57.364852826473
11:12:34.894890974241

如果您不需要这些皮秒,我们可以在 fmap 中进行乘法:

instance Arbitrary TimeOfDay where
arbitrary = TimeOfDay
<$> choose (0, 23)
<*> choose (0, 59)
<*> (fmap (MkFixed . (10^12 *)) (choose (0, 60)))

然后我们得到:

Main> sample (arbitrary :: Gen TimeOfDay)
15:00:53
14:02:44
14:44:40
12:40:12
09:55:39
10:06:02
15:00:51
15:52:23
16:59:05
22:38:45
20:23:15

关于haskell - TimeOfDay 的任意实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57843502/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com