Why am I getting this warning from GHCi?

I get a curious warning when matching with a pattern, but only when OverloadedStrings is enabled ...

$ ghci -Wall GHCi, version 6.12.1: http://www.haskell.org/ghc/ :? for help Loading package ghc-prim ... linking ... done. Loading package integer-gmp ... linking ... done. Loading package base ... linking ... done. Prelude> let fx = case (x :: [String]) of {[""] -> "root"; ["product", _] -> "product"; _ -> "unknown"} Prelude> :q Leaving GHCi. $ ghci -Wall -XOverloadedStrings GHCi, version 6.12.1: http://www.haskell.org/ghc/ :? for help Loading package ghc-prim ... linking ... done. Loading package integer-gmp ... linking ... done. Loading package base ... linking ... done. Prelude> let fx = case (x :: [String]) of {[""] -> "root"; ["product", _] -> "product"; _ -> "unknown"} <interactive>:1:10: Warning: Pattern match(es) are overlapped In a case alternative: [""] -> ... Prelude> let gx = case (x :: [String]) of {[] -> "root"; ["product", _] -> "product"; _ -> "unknown"} Prelude> let hx = case (x :: [String]) of {["oops"] -> "root"; ["product", _] -> "product"; _ -> "unknown"} Prelude> :q Leaving GHCi. 

I don’t understand why I received a warning for f using OverloadedStrings, especially since I did not receive a warning for f without OverloadedStrings, nor did I receive a warning for g or h , which differ from f only in the first pattern (which in all cases corresponds to only one specific value).

Assuming this is not a bug in the GHC, what am I missing?

+6
haskell warnings ghc case-statement
source share
2 answers

Here is a slightly simpler example that shows the same problem in GHC 6.12.3:

 f :: String -> Bool f "" = True f "a" = False g :: String -> Bool g "" = True g "aa" = False 

Only g receives an overlap warning with -XOverloadedStrings . I think this should be a mistake.

+4
source share

EDIT: basically you want this (after matching the conversion from (IsString b) => b to [Char] , but matching is done in consistent types):

 f :: [String] -> String f = matchf matchf :: (Show b, IsString a, Eq a, IsString b) => [a] -> b matchf x = case x of [""] -> "root"; ["product", _] -> "product"; _ -> "unknown" 

Otherwise, the GHC warns about the coincidence of "" :: String with "" :: (Data.String.IsString t) => t (literal). It would be interesting to know why (maybe an error?), Given that the literal "" defaults to String:

 Prelude> show ("" :: (Data.String.IsString t) => t) <interactive>:1:0: Warning: Defaulting the following constraint(s) to type `String' 

Your string should print Eq to match the pattern for working with -XOverloadedStrings. The string is still only [Char] with -XOverloadedStrings, but no string literals.

Another way to do this without causing a warning:

test.hs:

 import GHC.Exts(IsString(..)) newtype OString = OString String deriving (Eq, Show) instance IsString OString where fromString = OString f :: [OString] -> OString fx = case (x :: [OString]) of {[""] -> "root"; ["product", _] -> "product"; _ -> "unknown"} 

Run it:

 $ ghci -Wall -XOverloadedStrings GHCi, version 6.12.1: http://www.haskell.org/ghc/ :? for help Loading package ghc-prim ... linking ... done. Loading package integer-gmp ... linking ... done. Loading package base ... linking ... done. Prelude> :l test.hs [1 of 1] Compiling Main ( test.hs, interpreted ) Ok, modules loaded: Main. *Main> f [] OString "unknown" *Main> f [""] OString "root" *Main> f ["product"] OString "unknown" *Main> f ["product", "x"] OString "product" 

Source: http://www.haskell.org/ghc/docs/6.12.2/html/users_guide/type-class-extensions.html#overloaded-strings

+2
source share

All Articles