使用无限列表创建元素生成器
Create an elements generator with an infinite list
我正在玩 QuickCheck,偶然发现了一些奇怪的行为
sample $ elements [1..5]
按预期工作,但是
sample $ elements [1..]
在 ghci 中挂起,即使使用诸如 Int
的有限类型也是如此
sample $ elements [(1::Int)..]
为什么它不打印任意(双关语意:)大 Int
s?
更新
我已经使用
测试了@amalloy 的解释
sample $ elements ([1 .. ] :: [Int8])
确实会终止。
elements
随机均匀选择元素,这意味着它平均将达到 length / 2
项进入列表。对于无穷大的值,这是不可能的,对于像 [1..] :: [Int]
这样的大型有限列表,这仍然达到了 10 亿个项目,通过链表一次一个。相当慢的操作!
似乎 elements
的文档很少。除了非空之外,参数还应该是 finite。查看源码:
-- | Generates one of the given values. The input list must be non-empty.
elements :: [a] -> Gen a
elements [] = error "QuickCheck.elements used with empty list"
elements xs = (xs !!) `fmap` choose (0, length xs - 1)
它尝试计算输入列表的长度,这将导致无限列表上的无限循环。
我正在玩 QuickCheck,偶然发现了一些奇怪的行为
sample $ elements [1..5]
按预期工作,但是
sample $ elements [1..]
在 ghci 中挂起,即使使用诸如 Int
sample $ elements [(1::Int)..]
为什么它不打印任意(双关语意:)大 Int
s?
更新
我已经使用
测试了@amalloy 的解释sample $ elements ([1 .. ] :: [Int8])
确实会终止。
elements
随机均匀选择元素,这意味着它平均将达到 length / 2
项进入列表。对于无穷大的值,这是不可能的,对于像 [1..] :: [Int]
这样的大型有限列表,这仍然达到了 10 亿个项目,通过链表一次一个。相当慢的操作!
似乎 elements
的文档很少。除了非空之外,参数还应该是 finite。查看源码:
-- | Generates one of the given values. The input list must be non-empty.
elements :: [a] -> Gen a
elements [] = error "QuickCheck.elements used with empty list"
elements xs = (xs !!) `fmap` choose (0, length xs - 1)
它尝试计算输入列表的长度,这将导致无限列表上的无限循环。