具有不同结果的串联前后的列表检查

A list check before and after concatenation with different results

我有一个作业,代码很容易理解,但我找不到可能的解决方案。那是代码:

lucky:: [Integer] -> Bool
lucky (xs) = all (/=13) xs

catenate as []     = as
catenate as (b:bs) = b : (catenate as bs)

test_luck1 as bs = lucky as && lucky bs
test_luck2 as bs = lucky (catenate as bs)

所以问题是:对于哪个输入(两个函数相同),两个函数的布尔值不同,例如第一个为真,第二个为假,反之亦然。因此,第一个函数分别测试两个列表,第二个函数测试列表的串联。昨天我想了一整天,完全没有头绪。你们能帮我找到解决问题的技巧吗?

对于无限"lucky"bs和"unlucky"astest_luck1会终止,而test_luck2不会。

由于 catenate 的(有点奇怪)实现,函数以不同的顺序测试值,它在 bsas 之前。因此,test_luck1 首先测试 as,然后 bs,而 test_luck2 首先测试 bs,然后 as

P.S。根据@Mark Seemann 的评论,这可以被视为边界案例——抱歉剧透 ;)

再看看这个,我觉得我的评论太仓促了。除了 shinobi 的回答,我看不出这两个函数有任何 return 不同结果的方式。

并不是说这个 证明了 任何东西,但我写了一个 QuickCheck 属性 来验证 test_luck1 将始终 return 相同的假设结果为 test_luck2:

prop :: [Integer] -> [Integer] -> Bool
prop as bs =
  test_luck1 as bs == test_luck2 as bs

我已经 运行 这个 属性 进行了 1,000,000 次测试,它们都通过了,所以我认为 as 没有任何 'normal' 值和 bs 这将导致 test_luck1 的输出与 test_luck2.

的输出不同