Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why am I getting this warning from GHCi?

I'm getting a curious warning when pattern matching, 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 f x = 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 f x = case (x :: [String]) of {[""] -> "root"; ["product", _] -> "product"; _ -> "unknown"}

<interactive>:1:10:
    Warning: Pattern match(es) are overlapped
             In a case alternative: [""] -> ...
Prelude> let g x = case (x :: [String]) of {[] -> "root"; ["product", _] -> "product"; _ -> "unknown"}
Prelude> let h x = case (x :: [String]) of {["oops"] -> "root"; ["product", _] -> "product"; _ -> "unknown"}
Prelude> :q
Leaving GHCi.

I don't understand why I get the warning for f with OverloadedStrings, particularly since I don't get the warning for f without OverloadedStrings, and also don't get the warning for g or h, which differ from f only in the first pattern (which in all cases matches only a single particular value).

On the assumption that this is not a bug in GHC, what am I missing?

like image 421
dave4420 Avatar asked Sep 30 '10 17:09

dave4420


People also ask

How do I disable Ghci?

Quits GHCi. You can also quit by typing control-D at the prompt. Attempts to reload the current target set (see :load ) if any of the modules in the set, or any dependent module, has changed.

How do you stop an infinite loop in Ghci?

To stop it I just use Ctrl + c . And it works.

How do I stop Haskell running?

So the proper way to close haskell-shell is to hit Ctrl+D . Ctrl+D will not close ghci while it is executing code. Ctrl+Z, on the other hand, sends a signal that can't be caught or handled by the receiving process, so will always work (for any process, not just ghci).


2 Answers

Here's a slightly simpler example that shows the same issue in GHC 6.12.3:

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

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

Only g gets the overlap warning with -XOverloadedStrings. I think this has to be a bug.

like image 144
Travis Brown Avatar answered Sep 21 '22 11:09

Travis Brown


EDIT: Basically you want this (after matching converting back from (IsString b) => b into [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 GHC warns about matching "" :: String to "" :: (Data.String.IsString t) => t (literal). It would be interesting to find out why (probably a bug?) given that literal "" properly defaults to String:

Prelude> show ("" :: (Data.String.IsString t) => t)

<interactive>:1:0:
    Warning: Defaulting the following constraint(s) to type `String'

Your string must be deriving Eq for pattern matching to work with -XOverloadedStrings. String is still just [Char] with -XOverloadedStrings but string literals are not.

Another way to do this without triggering a warning:

test.hs:

import GHC.Exts(IsString(..))

newtype OString = OString String deriving (Eq, Show)
instance IsString OString where fromString = OString

f :: [OString] -> OString
f x = 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

like image 25
12 revs Avatar answered Sep 23 '22 11:09

12 revs