我正在使用一些HTTP代码并在构建时使用编译器警告(使用stack build
)警告我处理不同HTTP响应的情况下的重叠模式匹配。我正在使用包
import Network.HTTP.Types.Status (ok200, status203, Status)
import Network.HTTP.Conduit
import Network.HTTP.Types.Header
有问题的代码是:
... -- setup stuff for other functions.
-- getHttpResponse just uses "httpLbs req mngr" with some additional error wrapping
resp <- liftIO $ getHttpResponse mngr req
case resp of
Nothing -> ExceptT $ return $ Left $ create $ "could not get a response from " <> uri
Just r -> case responseStatus r of
ok200 -> do
case decode (responseBody r) of
Nothing -> throwIOError $ "could not decode object from " <> uri
Just xx -> return $ Right (xx, responseStatus r)
status203 -> do
case decode (responseBody r) of
Nothing -> throwIOError $ "could not decode object from " <> uri
Just xx -> return $ Left (xx, responseStatus r)
_ -> (throwIOError $ "non 200 server response "
<> T.pack (show $ responseStatus r)
<> " from " <> uri)
GHC给我的警告是:
Pattern match(es) are overlapped In a case alternative: status203 -> ... _ -> ...
我的200和203响应似乎都遵循第一条路线(返回Right
)并匹配ok200
。为了增加我的困惑,我最初在代码中输入了一个拼写错误,其中ok203
代替status203
。我不知道为什么,但该代码仍然编译,只是给出了类似的警告信息:
Pattern match(es) are overlapped In a case alternative: ok203-> ... _ -> ...
尽管ok203没有在我的代码库或我正在使用的任何软件包中定义(至少我能找到)。
有人能解释一下这里发生了什么吗?为什么这些模式重叠?而且,作为奖励,为什么我的代码甚至用ok203
编译?
答案 0 :(得分:5)
问题是ok203
和status203
是小写。所以它们在模式中被解释为绑定变量而不是构造函数来匹配。如果有不同状态的单独构造函数,那么您应该使用它们。否则,您应该使用警卫和==
来检查状态,而不是尝试匹配其值。这可能看起来像
case responseStatus r of
stat
| stat == ok203 -> ...
| stat == ... -> ...
| otherwise -> ...