Frage

Ich bekomme eine merkwürdige Warnung, wenn das Musterübereinstimmung angepasst wird, aber nur wenn überladene Strings aktiviert sind ...

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

Ich verstehe nicht, warum ich die Warnung dafür bekomme f mit überladenen Strings, zumal ich nicht die Warnung dafür bekomme f ohne überlastete Strings und auch nicht die Warnung dafür bekommen g oder h, was unterscheidet sich von f Nur im ersten Muster (was in allen Fällen nur mit einem einzigen bestimmten Wert übereinstimmt).

Was fehlt mir, unter der Annahme, dass dies kein Fehler in GHC ist?

War es hilfreich?

Lösung

Hier ist ein etwas einfacheres Beispiel, das das gleiche Problem in GHC 6.12.3 zeigt:

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

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

Nur g bekommt die Überlappungswarnung mit -XOverloadedStrings. Ich denke, das muss ein Fehler sein.

Andere Tipps

Bearbeiten: Im Grunde möchten Sie dies (nachdem Sie die Konvertierung von der Konvertierung von (IsString b) => b hinein [Char] Die Übereinstimmung erfolgt jedoch in konsistenten Typen):

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"

Andernfalls warnt GHC vor Matching "" :: String zu "" :: (Data.String.IsString t) => t (wörtlich). Es wäre interessant herauszufinden, warum (wahrscheinlich ein Fehler?) Angesichts dieser wörtlichen "" ordnungsgemäß standardmäßig zu String:

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

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

Ihre Zeichenfolge muss EQ für das Musteranpassung für die Arbeit mit -xoverloadedStrings abgeben. String ist immer noch nur [char] mit -xoverloadedstrings, aber String -Literale nicht.

Eine andere Möglichkeit, dies zu tun, ohne eine Warnung auszulösen:

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

Starte es:

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

Quelle: http://www.haskell.org/ghc/docs/6.12.2/html/users_guide/type-class-eutdessions.html#overloadd-Sstrings

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top