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.

我不明白为什么我会收到fOverloadedStrings 的警告,特别是因为我没有收到fOverloadedStrings 的警告,也没有收到gor的警告h,这与f第一个模式不同(总之case 仅匹配单个特定值)。

假设这不是 GHC 中的错误,我错过了什么?

4

2 回答 2

5

这是一个稍微简单的示例,它显示了 GHC 6.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"

否则 GHC 会警告匹配"" :: String"" :: (Data.String.IsString t) => t(literal)。""鉴于文字正确默认为字符串,找出原因(可能是错误?)会很有趣:

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

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

您的字符串必须派生 Eq 才能使用 -XOverloadedStrings 进行模式匹配。字符串仍然只是带有 -XOverloadedStrings 的 [Char] 但字符串文字不是。

在不触发警告的情况下执行此操作的另一种方法:

测试.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 回答