[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