为什么我会从GHCI那里得到此警告?
-
26-09-2019 - |
题
在模式匹配时,我会得到一个好奇的警告,但是只有在启用了超载串...
$ 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
带有过载,特别是因为我没有得到警告 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
. 。我认为这必须是一个错误。
其他提示
编辑:基本上您需要这个(匹配从 (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以进行模式匹配以与-XoverLoadStrings一起使用。字符串仍然只是[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"
不隶属于 StackOverflow