[GHC] #13517: No warnings produced, yet the pattern matching fails at runtime.

#13517: No warnings produced, yet the pattern matching fails at runtime. -------------------------------------+------------------------------------- Reporter: | Owner: (none) timotej.tomandl | Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 8.0.1 Keywords: | Operating System: Unknown/Multiple PatternMatchWarnings | Architecture: | Type of failure: None/Unknown Unknown/Multiple | Test Case: | Blocked By: Blocking: | Related Tickets: Differential Rev(s): | Wiki Page: -------------------------------------+------------------------------------- The code below should produce a warning about a non-exhaustive pattern in the failure, yet it compiles alright. {{{ #!div style="font-size: 80%" {{{#!haskell {-# OPTIONS_GHC -Wall -Werror #-} action :: (Monad m)=>t->m (Maybe a) action _=return Nothing failure :: (Monad m)=>Int->(m Int) failure x=do Just y<-action x return y main :: IO() main=do y<-failure 1 putStrLn $ (show y) }}} }}} The same should be the case if we replace the definition of failure with {{{ #!div style="font-size: 80%" {{{#!haskell failure :: (Monad m)=>Int->(m Int) failure x=(action x)>>=(\(Just y)->return y) }}} }}} yet once again no warnings are produced. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/13517 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#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.1... 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
participants (1)
-
GHC