[GHC] #13517: No warnings produced, yet the pattern matching fails at runtime.
GHC
ghc-devs at haskell.org
Mon Apr 3 14:38:24 UTC 2017
#13517: No warnings produced, yet the pattern matching fails at runtime.
-------------------------------------+-------------------------------------
Reporter: timotej.tomandl | Owner: (none)
Type: bug | Status: closed
Priority: normal | Milestone:
Component: Compiler | Version: 8.0.1
Resolution: invalid | Keywords:
| PatternMatchWarnings
Operating System: Unknown/Multiple | Architecture:
| Unknown/Multiple
Type of failure: None/Unknown | Test Case:
Blocked By: | Blocking:
Related Tickets: | Differential Rev(s):
Wiki Page: |
-------------------------------------+-------------------------------------
Changes (by RyanGlScott):
* status: new => closed
* resolution: => invalid
Comment:
Both of these examples are working as expected, for some definition of
"expected".
One thing to note here: the versions of `failure` you've given are not
quite semantically equivalent. I'll go over the second example first,
since it's easier to explain:
{{{#!hs
failure :: (Monad m)=>Int->(m Int)
failure x=(action x)>>=(\(Just y)->return y)
}}}
You're right—this is partial, and moreover, `-Wall` doesn't warn about
this. There //is// a flag that warns about this, however: `-Wincomplete-
uni-patterns`. As for why it's not a part of `-Wall`,
[https://downloads.haskell.org/~ghc/8.0.1/docs/html/users_guide/using-
warnings.html#ghc-flag--Wincomplete-uni-patterns to quote the users'
guide:]
> This option isn’t enabled by default because it can be a bit noisy, and
it doesn’t always indicate a bug in the program. However, it’s generally
considered good practice to cover all the cases in your functions, and it
is switched on by `-W`.
So you can enable `-Wincomplete-uni-patterns` or `-W` if you want a
warning for this.
Now, back to the first example:
{{{#!hs
failure :: (Monad m)=>Int->(m Int)
failure x=do
Just y<-action x
return y
}}}
Pattern matching in `do`-notation is handled a bit differently than in
other contexts. The Haskell Report has
[https://www.haskell.org/onlinereport/haskell2010/haskellch3.html#x8-470003.14
a nice section] on this. Effectively, that implementation of `failure`
gets desugared down to this:
{{{#!hs
failure :: Monad m => Int -> m Int
failure x = let ok (Just y) = return y
ok _ = fail "Pattern match failure in do
expression..."
in action x >>= ok
}}}
Which is actually total! But it does rely on the `fail` method of `Monad`,
which some find a bit unsavory. Relatedly, `fail` will eventually be
[https://prime.haskell.org/wiki/Libraries/Proposals/MonadFail split out]
of `Monad` and into a separate `MonadFail` class at some point in the
future.
It's important to note that not all implementations of `fail` throw
exceptions. For instance, here are some demonstrations of `failure` used
on particular `Monad`s:
{{{
λ> failure 1 :: IO Int
*** Exception: user error (Pattern match failure in do expression at
Bug.hs:7:5-10)
λ> failure 1 :: Maybe Int
Nothing
λ> failure 1 :: [Int]
[]
}}}
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/13517#comment:1>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list