Почему я получаю это предупреждение от GHCi? - PullRequest
6 голосов
/ 30 сентября 2010

Я получаю любопытное предупреждение при сопоставлении с образцом, но только когда включена опция OverloadedStrings ...

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

Я не понимаю, почему я получаю предупреждение для f с OverloadedStrings, тем более что я не получаю предупреждение для f без OverloadedStrings, а также не получаю предупреждение для g или h, которые отличаются от f только первым шаблоном (который во всех случаях соответствует только одному конкретному значению).

При условии, что это не ошибка в GHC, что мне не хватает?

Ответы [ 2 ]

4 голосов
/ 01 октября 2010

Вот несколько более простой пример, который показывает ту же проблему в GHC 6.12.3:

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

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

Только g получает предупреждение о перекрытии с -XOverloadedStrings.Я думаю, что это должно быть ошибкой.

2 голосов
/ 01 октября 2010

РЕДАКТИРОВАТЬ: В основном вы хотите это (после сопоставления преобразование обратно из (IsString b) => b в [Char], но сопоставление выполняется в согласованных типах):

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"

В противном случае GHC предупреждает о сопоставлении "" :: String с "" :: (Data.String.IsString t) => t (буквальный).Было бы интересно выяснить, почему (возможно, ошибка?), Учитывая, что литерал "" по умолчанию имеет значение String:

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

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

Ваша строка должна быть производной Eq для сопоставления с шаблоном для работы с -XOverloadedStrings.Строка по-прежнему просто [Char] с -XOverloadedStrings, но строковые литералы - нет.

Другой способ сделать это без предупреждения:

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

Запустите его:

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

Источник: http://www.haskell.org/ghc/docs/6.12.2/html/users_guide/type-class-extensions.html#overloaded-strings

...