7

パターンマッチング時に不思議な警告が表示されますが、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.

OverloadedStringsを使用すると警告が表示される理由がわかりませんf。特に、OverloadedStringsを使用しないと警告が表示されないためです。また、またはfの警告も表示されません。これは、最初のパターン(すべてのパターン)のみとは異なります。ケースは単一の特定の値にのみ一致します)。ghf

これがGHCのバグではないと仮定すると、何が欠けていますか?

4

2 に答える 2

5

これは、GHC6.12.3で同じ問題を示す少し簡単な例です。

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

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

gとの重複警告のみを取得し-XOverloadedStringsます。これはバグだと思います。

于 2010-09-30T21:47:47.317 に答える
2

編集:基本的にあなたはこれを望んでいます(から(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"

"" :: Stringそれ以外の場合、GHCは"" :: (Data.String.IsString t) => t(リテラル)とのマッチングについて警告します。""リテラルが適切にデフォルトで文字列になっている理由(おそらくバグ?)を見つけるのは興味深いでしょう。

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

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

パターンマッチングが-XOverloadedStringsで機能するには、文字列がEqを導出している必要があります。文字列はまだ-XOverloadedStringsを使用した[Char]ですが、文字列リテラルはそうではありません。

警告をトリガーせずにこれを行う別の方法:

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

于 2010-09-30T21:33:35.190 に答える