Haskell错误:错误:[-Wunused-matches,-Werror=unused-matches]已定义但未使用:“x”

flvlnr44  于 2023-01-05  发布在  其他
关注(0)|答案(1)|浏览(224)

我得到这种错误:

error: [-Wunused-matches, -Werror=unused-matches]
Defined but not used: `xs'

我的密码是

gameToString :: Game -> String
gameToString ((x):(y):(z):(xs)) = (rowToString x) ++ (rowToString y) ++ (rowToString z)

哪里错了?

g2ieeal7

g2ieeal71#

在函数定义中,如果您对左侧的变量进行模式匹配,而该变量没有出现在右侧:

gameToString (x:y:z:xs) = ... no "xs" in here ...
                    ^^
                     `-- "xs" appears here

这是法律的的Haskell代码,但是它 * 可能 * 表示一个编程错误。因此,有一个编译器标志-Wunused-matches,如果发生这种情况,它会生成一个编译警告。如果你指定-Wall,它会打开很多警告,包括这个。
通常情况下,编译仍然会成功,但如果您还指定了编译器标志-Werror,则会将所有警告都转换为编译错误。
因此,您正在编译法律的的Haskell代码,但可能带有编译器标志-Wall -Werror,这会生成一个升级为错误的警告。
要解决此问题,您需要向Haskell指明xs是故意不使用的。您可以使用_通配符代替xs来完成此操作:

gameToString (x:y:z:_) = ...

或使用以下划线开头的名称:

gameToString (x:y:z:_xs) = ...

两者都将抑制此警告。
如果-Wall打开(或者-Wincomplete-patterns打开),你会收到另一个致命警告,因为你的gameToString定义只匹配长度为3或更长的列表。这将导致Pattern match(es) are non-exhaustive警告/错误。为了避免这种情况,你需要添加另一个case来处理无效游戏:

gameToString :: Game -> String
gameToString (x:y:z:_) = rowToString x ++ rowToString y ++ rowToString z
gameToString _ = error "internal error: invalid Game"

相关问题