2010-09-30 20 views
6

me estoy haciendo una curiosa advertencia cuando la coincidencia de patrones, pero sólo cuando está activado OverloadedStrings ...¿Por qué recibo esta advertencia 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. 

No entiendo por qué me da la advertencia para f con OverloadedStrings, sobre todo porque no lo hago Obtiene la advertencia para f sin OverloadedStrings, y tampoco recibe la advertencia para g o h, que difieren de f solo en el primer patrón (que en todos los casos coincide solo con un valor particular).

Suponiendo que esto no es un error en GHC, ¿qué me estoy perdiendo?

+0

¿Es posible que '" "' esté sobrecargado de modo que '[" "]' sea equivalente a '[_]'? – Gabe

+0

No, está haciendo coincidir como si fuera '[" "]', no como si fuera '[_]'. – dave4420

+0

¿Has probado esto en GHC 7.0? –

Respuesta

4

Aquí está un poco más sencillo ejemplo que muestra el mismo problema en GHC 6.12.3:

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

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

Solo g recibe la advertencia de superposición con -XOverloadedStrings. Creo que esto tiene que ser un error.

+0

Sí, esto es claramente un error.Lo que también es extraño es que eliminar la firma de tipo de 'g' (haciendo que su tipo sea inferido como' (IsString t, Eq t) => t -> Bool') hace que la advertencia desaparezca. –

2

EDIT: Básicamente desea que este (después de la conversión de juego de vuelta de (IsString b) => b en [Char] pero se realiza la casación en tipos coherente):

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" 

De lo contrario GHC advierte sobre la correspondencia de "" :: String a "" :: (Data.String.IsString t) => t (literal). Sería interesante averiguar por qué, dado que literales "" valores predeterminados correctamente para cuerdas (probablemente un error?):

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

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

La cadena debe estar derivando la ecuación de coincidencia de patrones para trabajar con -XOverloadedStrings. String sigue siendo solo [Char] con -XOverloadedStrings pero los literales de cadena no lo son.

Otra manera de hacer esto sin que se dispare una advertencia:

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 que:

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

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

+0

Sin embargo, estoy haciendo un patrón de coincidencia en 'Cadena 'ordinaria (en mi programa real, necesito cadenas sobrecargadas en una parte diferente de mi código), por lo que ya ha derivado' Eq'. Entonces, no veo cómo esto ayuda? – dave4420

+1

@Dave Hinton: está tratando de comparar manzanas con naranjas, pero GHC no está seguro de poder convertir las naranjas en manzanas de forma segura antes de la comparación (específicamente, está teniendo problemas con ""). Mientras que la entrada de función es de tipo String, lo que está comparando con (literales de cadena) primero tiene que convertirse en cadenas. – vls

Cuestiones relacionadas