为什么我从GHCi得到这个警告?
我得到一个奇怪的警告时,模式匹配,但只启用OverloadedStrings当...为什么我从GHCi得到这个警告?
$ 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,特别是因为我不在没有OverloadedStrings的情况下获得f
的警告,也不会收到g
或h
的警告,这些警告仅在第一种模式(在所有情况下仅匹配单个特定值)与f
不同。
假设这不是GHC中的错误,我错过了什么?
这里有一个稍微简单在GHC 6.12.3中显示相同问题的示例:
f :: String -> Bool
f "" = True
f "a" = False
g :: String -> Bool
g "" = True
g "aa" = False
只有g
得到-XOverloadedStrings
的重叠警告。我认为这必须是一个错误。
是的,这很明显是一个错误。奇怪的是,删除'g'的类型签名(导致它的类型被推断为'(IsString t,Eq t)=> t - > Bool')使得警告消失。 – 2010-10-02 14:38:19
编辑:基本上,你想要这个(匹配来自(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
(文字)。这将给予是有趣的,看看为什么字面""
正确默认字符串(可能是一个错误?):
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"
有没有可能重载'''',使得[[“”]'等于'[_]'? – Gabe 2010-09-30 17:58:32
不,它的匹配就好像它是[[“”]',而不是它就是'[_]'。 – dave4420 2010-09-30 18:44:15
你在GHC 7.0上测试过了吗? – 2010-09-30 18:56:38