2010-09-30 20 views
6

Ben meraklı bir uyarı desen eşleştirme alıyorum ama OverloadedStrings etkinleştirildiğinde ben OverloadedStrings ile f için uyarı almak neden sadece ...Bu uyarı neden GHCi'den geliyor? Bilmiyorum özellikle beri

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

anlamıyorum OverloadedStrings olmadan f için uyarı almak ve aynı zamanda ff sadece ilk desende (tüm durumlarda yalnızca tek bir belirli bir değerle eşleşir) farklı olan uyarı almak için uyarı almayın (g).

Bu durumun GHC'de bir hata olmadığı varsayımıyla neyi özlüyorum?

+0

'' '' '' '' '' '' '' '' '' '' '' '' ile eşdeğerde aşırı yüklenebilir mi? – Gabe

+0

Hayır, sanki "[" "], sanki" [_] "gibi değil. – dave4420

+0

Bunu GHC 7.0 üzerinde test ettiniz mi? –

cevap

4

biraz basittir GHC 6.12.3'te aynı sorunu gösteren örnek:

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

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

Yalnızca g, -XOverloadedStrings ile çakışma uyarısını alır. Bunun bir hata olması gerektiğini düşünüyorum.

+0

Evet, bu oldukça açık bir hata.Ayrıca garip olan şey, 'g' türünün imzasının kaldırılmasıdır (türünün '(IsString t, Eq t) => t -> Bool' gibi çıkması), uyarının ortadan kalkmasına neden olur. –

2

DÜZENLEME: Temel olarak ([Char] içine (IsString b) => b geri dönüştürme eşleşen sonra ancak eşleştirme tutarlı türlerinde yapılır) bu istiyorum:

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" 

Aksi GHC "" :: String"" :: (Data.String.IsString t) => t için (literal) ile eşleşen hakkında uyarır. Nedenini öğrenmek ilginç olurdu verilen String literal "" düzgün varsayılan ki (muhtemelen bir hata?):

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

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

Sizin dize -XOverloadedStrings çalışmak eşleşen örüntü Denk kaynaklanan olmalıdır. Dize hala -XOverloadedStrings ile sadece [Char], ancak dize değişmezleri değildir.

uyarı tetikleme olmadan bunu bir başka yolu:

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

çalıştırın o:

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

Kaynak: İşte http://www.haskell.org/ghc/docs/6.12.2/html/users_guide/type-class-extensions.html#overloaded-strings

+0

Ben sıradan 'String's (ben benim gerçek programında, kodumun farklı bir parçası aşırı yüklü dizeleri gerekir) desen eşleştirme duyuyorum, bu yüzden zaten' Eq' türetilmiştir. Yani, bunun nasıl yardımcı olduğunu görmüyorum? – dave4420

+1

@Dave Hinton: Elmaları portakallarla karşılaştırmaya çalışıyor ama GHC, portakalın elmadan önce güvenli bir şekilde elmalarıma dönüşebileceğinden emin değil (özellikle de "" ile sorun yaşıyor). İşlev girdisi String türündeyken, onu (dize değişmezleri) karşılaştırdığınız şey önce Dizeler olarak dönüştürülmelidir. – vls