如何让 GHC 对 do 块中的不完整模式绑定发出警告?
Posted
技术标签:
【中文标题】如何让 GHC 对 do 块中的不完整模式绑定发出警告?【英文标题】:How can I get GHC to warn about incomplete pattern bindings in do blocks? 【发布时间】:2016-10-07 20:54:47 【问题描述】:以下 Haskell 程序已损坏,因为它执行了不完整的模式绑定:
main = do
[x] <- pure ["foo", "bar"]
print x
如果你编译它,你不会收到任何警告:
$ ghc -fwarn-incomplete-uni-patterns -o example example.hs
[1 of 1] Compiling Main ( example.hs, example.o )
Linking example ...
但如果你运行它,你会得到:
example: user error (Pattern match failure in do expression at example.hs:2:3-5)
我想以某种方式获得编译器警告。
从文档中,我原以为 -fwarn-incomplete-uni-patterns
会这样做,因为 do
块去糖:
desugared = pure ["foo", "bar"] >>= \[x] -> print x
确实,将其添加到示例文件中确实会产生警告:
$ ghc -fwarn-incomplete-uni-patterns -o example example.hs
[1 of 1] Compiling Main ( example.hs, example.o )
example.hs:1:37: Warning:
Pattern match(es) are non-exhaustive
In a lambda abstraction:
Patterns not matched:
[]
_ : (_ : _)
当我在 do
块内执行相同操作时,如何收到类似的警告?
$ ghc --version
The Glorious Glasgow Haskell Compilation System, version 7.10.3
【问题讨论】:
请注意,带有<-
的不完整模式最终会调用该monad 的fail
函数。所以至少在旧版本的 Haskell 中,代码本身并没有错,可能会有有效的结果:Prelude> let x::[Int]; x = do [y] <- return [1,2]; return y Prelude> x []
或者将x :: [Int]
更改为x :: Maybe Int
你会得到Nothing
。
确实,解决这个问题需要知道fail
何时返回底部,这很棘手。我仍然希望[ f x | Just x <- list ]
和等效的do Just x <- list ; return (f x)
不触发警告。不知道如何才能真正实现这一目标......
我建议您为 -fwarn-implicit-fail
或类似的文件提交 GHC 功能请求,当脱糖插入对 fail
的调用时发出警告,而该调用不在源中。
我认为期望是当您以这种方式使用<-
时,您知道自己在做什么,并且接受fail
可能会被调用。毕竟,您只能指定一个模式,因此您应该知道该模式是否详尽。这也是一个非常方便的功能 - 仅Just ... <-
模式在 Hackage 中就出现了数百次。看到将其添加到 GHC 时进行的原始讨论会很有趣 - 我相信利弊已被广泛讨论。
ghc.haskell.org/trac/ghc/ticket/5813 "为失败的模式匹配提供编译器警告"
【参考方案1】:
就目前而言,为了避免这种怪癖导致的错误,您唯一能做的就是避免使用 MonadFail
实例的 monad(在最近的 GHC 版本中,不完整的绑定模式会导致编译错误)。
There is already an issue for this。还有一个声明为这个解决方案辩护,指出它可能是完全可取的,因此不值得警告:
这实际上是正确有用的行为。使用类似的东西
do Just x <- xs Just y <- ys return (x,y)
会做正确的事,如果 xs 或 ysresults 为 Nothing,则失败。为了 例如,在 list monad 中,它将创建 两个列表的非 Nothing 成员。解析单子可以回溯和 尝试另一条路线,IO monad 将创建一个有用的(和 确定性/可捕获)异常指向确切的文件和行 模式匹配的编号。 do 符号是唯一的地方 haskell 允许我们挂钩到模式匹配机制 通用的语言。
【讨论】:
以上是关于如何让 GHC 对 do 块中的不完整模式绑定发出警告?的主要内容,如果未能解决你的问题,请参考以下文章