【问题标题】:QuickCheck - Non exhaustive patterns in function - HaskellQuickCheck - 功能中的非详尽模式 - Haskell
【发布时间】:2018-11-06 10:35:02
【问题描述】:

我有两个功能。一种是使用模式实现的,另一种是使用密集列表实现的。我想用 QickCheck 检查结果是否始终相同。

pares xs = [a | a <- xs , mod a 2 == 0]
cuadrados xs = [x^2 | x <- pares xs ]
cuadrados'' [] = []
cuadrados'' (x:xs) = [x^2] ++ cuadrados'' xs
cuadrados' (x:xs)  = cuadrados'' (pares (x:xs))

我正在尝试:

prop_cuadrados xs = cuadrados xs == cuadrados' xs

当我尝试 quickCkeck prop_cuadrados 时,输出如下:

*Main> quickCheck prop_cuadrados *** 失败的! (经过1次测试): 例外: session4.hs:10:1-47:函数 cuadrados 中的非详尽模式 []

我该如何解决这个问题? 谢谢

【问题讨论】:

  • cuadrados' 没有空列表案例,所以当 quickCheck 生成测试 cuadrados [] == cuadrados' [] 时它会失败。
  • 没错,您的cuadrados' 仅适用于非-空列表,您应该使用cuadrados' xs = cuadrados'' (pares xs),或者更好的事件cuadrados' = cuadrados'' . pares
  • 丢失的模式不仅可以由 QuickCheck 找到,如果您启用警告,GHC 本身也可以找到。
  • 始终使用-Wall 编译确实是明智的:就像chi 所说,编译器已经可以生成未定义函数的模式列表。
  • 不相关,但不要使用[x] ++ y,x:y 可以。另外,不要在不需要时重新实现map:cuadrados'' = map (^2)。

标签: haskell ghci haskell-platform


【解决方案1】:

如果我们在 GHC 中应用 -Wall(它会自动启用 -Wincomplete-patterns)或者只是手动尝试找到的反例,我们可以立即发现该问题。

QuickCheck 发现 xs = [] 作为反例。那么让我们来看看cuadrados':

cuadrados' []

此时,我们无法继续,因为cuadrados' 只绑定一个模式:(x:xs)。不幸的是,[] 无法匹配该模式,您最终会遇到错误。要修复它,只需添加另一个模式:

cuadrados' []     = []
cuadrados' (x:xs) = …

或者直接使用

cuadrados' xs = cuadrados'' (pares xs)

因为我们没有明确使用第一个元素。

话虽如此,pares 是 filter even,cuadrados 是 map (^2) . filter even。尽量多使用标准库和高阶函数。

【讨论】:

  • 如果您的代码有效,请随时前往Code Review。
猜你喜欢
  • 1970-01-01
  • 2018-09-06
  • 2021-11-30
  • 2019-01-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多