2010-09-30 4 views
6

Je reçois un avertissement curieux lorsque la correspondance de motif, mais seulement quand OverloadedStrings est activé ...Pourquoi est-ce que je reçois cet avertissement de GHCi?

$ 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. 

Je ne comprends pas pourquoi je reçois l'avertissement pour f avec OverloadedStrings, d'autant plus que je ne obtenir l'avertissement pour f sans OverloadedStrings, et aussi ne pas obtenir l'avertissement pour g ou h, qui diffèrent de f seulement dans le premier modèle (qui dans tous les cas ne correspond qu'à une seule valeur particulière).

En supposant que ce n'est pas un bug dans GHC, qu'est-ce qui me manque?

+0

Est-il possible que '" "' soit surchargé de sorte que '[" "]' soit équivalent à '[_]'? – Gabe

+0

Non, c'est comme s'il s'agissait de '[" "]', pas comme si c'était [_] '. – dave4420

+0

Avez-vous testé cela sur GHC 7.0? –

Répondre

4

est ici un peu plus simple exemple qui montre le même problème dans GHC 6.12.3:

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

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

Seul le g obtient l'avertissement de chevauchement avec -XOverloadedStrings. Je pense que cela doit être un bug.

+0

Oui, c'est clairement un bug.Ce qui est également étrange, c'est que la suppression de la signature de type de 'g' (faisant que son type soit déduit comme' (IsString t, Eq t) => t -> Bool') fait disparaître l'avertissement. –

2

EDIT: Fondamentalement, vous voulez ce (après correspondant à la conversion de retour de (IsString b) => b en [Char], mais la correspondance est établie dans les types cohérents):

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" 

Sinon GHC met en garde contre "" :: String correspondant à "" :: (Data.String.IsString t) => t (littérale). Il serait intéressant de savoir pourquoi, étant donné que "" littérales correctement par défaut String (probablement un bug?):

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

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

Votre chaîne doit dériver l'équation pour le modèle correspondant à travailler avec -XOverloadedStrings. String est toujours juste [Char] avec -XOverloadedStrings mais les littéraux de chaîne ne le sont pas.

Une autre façon de le faire sans déclencher un avertissement:

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"} 

Lancez-:

$ 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

+0

Je fais correspondre des motifs sur des 'String's ordinaires (dans mon vrai programme, j'ai besoin de chaînes surchargées dans une partie différente de mon code), donc il a déjà dérivé' Eq'. Donc, je ne vois pas comment cela aide? – dave4420

+1

@ Dave Hinton: il essaie de comparer les pommes aux oranges, mais GHC n'est pas sûr qu'il peut convertir des oranges en pommes en toute sécurité avant la comparaison (en particulier, il a des problèmes avec ""). Alors que l'entrée de la fonction est de type String, ce que vous comparez à (littéraux de chaîne) doit d'abord être converti en chaînes. – vls

Questions connexes