解析体代码中的什么使标头读取不会失败?

  • 本文关键字:读取 失败 代码 haskell types
  • 更新时间 :
  • 英文 :


我正在尝试构建一个简单的网络抓取器,以便从维基百科获取一些文本语料库。我想使用他们的REST API在Haskell中构建一个简单的HTTP客户端。

为此,我转向了Network.HTTP.Simple包。 在他们的教程中,他们提供了以下代码片段,我可以很好地运行。

#!/usr/bin/env stack
{- stack --install-ghc --resolver lts-5.13 runghc
--package http-conduit
--package yaml
-}
{-# LANGUAGE OverloadedStrings #-}
import           Data.Aeson            (Value)
import qualified Data.ByteString.Char8 as S8
import qualified Data.Yaml             as Yaml
import           Network.HTTP.Simple
main :: IO ()
main = do
response <- httpJSON "http://httpbin.org/get"
putStrLn $ "The status code was: " ++
show (getResponseStatusCode response)
print $ getResponseHeader "Content-Type" response
S8.putStrLn $ Yaml.encode (getResponseBody response :: Value)

为了理解代码,我注释掉了最后一行(以S8.putStrLn开头的那行...,现在代码中断了。错误是

No instance for (Yaml.FromJSON a0) arising from a use of ‘httpJSON’
The type variable ‘a0’ is ambiguous
Note: there are several potential instances:
instance Yaml.FromJSON
aeson-1.2.1.0:Data.Aeson.Types.Internal.DotNetTime
-- Defined in ‘aeson-1.2.1.0:Data.Aeson.Types.FromJSON’
instance Yaml.FromJSON Value
-- Defined in ‘aeson-1.2.1.0:Data.Aeson.Types.FromJSON’
instance Yaml.FromJSON
attoparsec-0.13.1.0:Data.Attoparsec.Number.Number
-- Defined in ‘aeson-1.2.1.0:Data.Aeson.Types.FromJSON’
...plus 78 others

所以我的问题是:(1(所以我的猜测是,getResponseBody强制httpJSON的类型签名,所以歧义被解除了。但是怎么做呢?(2(我可以在不调用getResponseBody的情况下消除表达式的歧义吗?我有哪些选项可以修复多态函数的返回类型?

编辑:我正在用cabal run运行它,因为我还没有安装堆栈。我没想到这会改变事情,但谁知道呢......可能会提供线索。

类型检查

我们有这个签名:getResponseBody :: Response a -> a.

起初,就在httpJSON之后,我们已经response :: Response a0了一些未知a0

然后我们写getResponseBody response,它的类型a0,仍然未知。

然后我们注释getResponseBody response :: Value,所以a0 ~ Value,现在实例解析有一个具体的类型可以使用。

限制response类型的替代方法

您可以在使用response值的任何位置直接对其进行注释,例如,您可以在代码段中间编写getResponseStatusCode (response :: Response Value)

使用ScopedTypeVariables扩展名,您还可以注释绑定它的模式:(response :: Response Value) <- httpJSON "..."

a0类型变量也出现在httpJSON的结果类型中,因此您也可以对其进行注释。

response <- httpJSON "..." :: IO (Response Value)

对于TypeApplications,这里有更多的选择,任何一个都应该足以让类型检查器推断出a0 ~ Value

response <- httpJSON @_ @Value "..."
getResponseStatusCode @Value response
getResponseHeader @Value "..." response
getResponseBody @Value response

最新更新