2010-09-30 34 views
6

Sto diventando un curioso avviso quando pattern matching, ma solo quando è abilitato OverloadedStrings ...Perché ricevo questo avviso da 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. 

Non capisco il motivo per cui ho l'avvertimento per f con OverloadedStrings, soprattutto perché non lo faccio ottenere l'avviso per f senza OverloadedStrings e inoltre non ricevere l'avviso per g o h, che differiscono da f solo nel primo modello (che in tutti i casi corrisponde solo a un singolo valore particolare).

Partendo dal presupposto che questo non è un bug in GHC, cosa mi manca?

+0

E 'possibile che "" "' sia sovraccarico tale che '[" "]' è equivalente a '[_]'? – Gabe

+0

No, corrisponde come se fosse '[" "]', non come se fosse '[_]'. – dave4420

+0

Hai provato questo su GHC 7.0? –

risposta

4

Ecco un po 'più semplice esempio che mostra lo stesso problema in GHC 6.12.3:

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

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

Solo g ottiene la sovrapposizione di avvertimento con -XOverloadedStrings. Penso che questo deve essere un bug.

+0

Sì, questo è chiaramente un bug.Ciò che è anche strano è che la rimozione della firma del tipo di 'g' (causando che il suo tipo sia dedotto come' (IsString t, Eq t) => t -> Bool') fa sparire l'avviso. –

2

EDIT: In pratica si vuole che questa (dopo aver confrontato La riconversione da (IsString b) => b in [Char] ma abbinamento è fatto in tipi in funzione):

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" 

Altrimenti GHC mette in guardia sulla corrispondenza "" :: String per "" :: (Data.String.IsString t) => t (letterale). Sarebbe interessante scoprire il motivo per cui, dato che letterali "" correttamente il default è String (probabilmente un bug?):

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

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

La stringa deve essere derivante Eq per pattern matching per lavorare con -XOverloadedStrings. String è ancora solo [Char] con -XOverloadedStrings ma i letterali stringa non lo sono.

Un altro modo per farlo senza innescare un avvertimento:

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

eseguirlo:

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

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

+0

I am pattern matching su ordinario 'String' s però (nel mio vero programma, ho bisogno di stringhe sovraccariche in una parte diversa del mio codice), quindi ha già derivato' Eq'. Quindi, non vedo come questo aiuti? – dave4420

+1

@Dave Hinton: sta provando a confrontare le mele con le arance, ma GHC non è sicuro di poter convertire le arance in mele in modo sicuro prima del confronto (in particolare, ha problemi con ""). Mentre l'input della funzione è di tipo String, per cosa lo stai confrontando (stringhe letterali) devi prima convertirlo in stringhe. – vls

Problemi correlati