以下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
答案 0 :(得分:0)
就目前而言,为了避免由于该怪癖而引起的错误,您唯一可以做的就是避免使用MonadFail
实例的monad(在最近的GHC版本中,不完整的绑定模式将导致编译错误)。
There is already an issue for this。还有一条声明为该解决方案辩护,指出它可能是完全合乎需要的,因此不值得警告:
这实际上是正确的有用行为。使用类似的东西
do Just x <- xs Just y <- ys return (x,y)
将做正确的事情,如果xs或ysresults为Nothing则失败。对于 例如,在清单monad中,它将创建 非两个列表的成员。解析的monad可能会回溯并 尝试其他路线,IO monad将创建一个有用的(并且 确定性/可捕获)异常,指向确切的文件和行 模式匹配的编号。 do表示法是唯一的地方 haskell,它使我们能够参与到模式匹配机制中 一般的语言。