我正在尝试使用HTTP-condit库,并具有一个简单的示例:
#!/usr/bin/env stack
{- stack
--resolver lts-7.12
--install-ghc
runghc
--package http-conduit
-}
{-# LANGUAGE OverloadedStrings #-}
import Network.HTTP.Conduit
import Data.ByteString.Lazy.Internal
getUrl :: IO (Data.ByteString.Lazy.Internal.ByteString) ---eeew!
getUrl = do
resp <- simpleHttp "http://www.stackoverflow.com"
return resp
我从这篇文章中了解到,我应该更喜欢对[char]或字符串的bytestring响应。我以为Pragma的过载可能会越来越少,但似乎并没有改变我的外类型。
该功能效果很好,忠实地打印出了SO主页的简单http响应,但是该类型的签名看起来确实很丑:
getUrl :: IO (Data.ByteString.Lazy.Internal.ByteString)
我不得不说,我从互联网示例中看到了很少的东西(伙计,我们的点比椭圆形的Java进口要多)。是对的吗?如果我想返回回复,然后开始解析,例如用hxt或tagsoup或attoparsec进行解析,这是正确的方法还是类型签名?
我注意到,例如,当我开始添加参数的能力时,这会变得更加丑陋,例如提供不同的URL:
import Network.HTTP.Conduit
import Data.ByteString.Lazy.Internal
-- alright, first arg is now string for my url...
getUrl :: String -> IO (Data.ByteString.Lazy.Internal.ByteString)
getUrl url = do
resp <- simpleHttp url
return resp
main :: IO (ByteString) -- what?! inside the () ?
main = do
getUrl "https://www.stackoverflow.com"
这似乎不太健康。我应该如何理解如何正确构建它?
您可以随时使用其合格路径编写类型。但是,由于您已经导入了Data.ByteString.Lazy.Internal
,除非您在范围中有其他ByteString
类型(例如严格的范围),否则只需省略Data.ByteString.Lazy.Internal
:
getUrl :: IO ByteString
另外,除非您有一些特殊需要导入Internal
,否则我建议您只导入Data.ByteString.Lazy
(还导出您正在使用的懒惰ByteString
类型)。如果您在范围中同时具有严格和懒惰的ByteString
,我将其导入资格:
import qualified Data.ByteString as BS
import qualified Data.ByteString.Lazy as BL
然后 BS.ByteString
是严格的类型, BL.ByteString
懒惰的人 - 无需写出完整的 Data.ByteString.ByteString
或 Data.ByteString.Lazy.ByteString
。
也值得一提的(感谢@duplode),两个bytestring模块通常都是最有资格进口的,因为它们定义了一大堆与前奏的功能(彼此之间)。
>最后,请注意,帕伦斯本身无济于事。(ByteString)
和ByteString
是相同的。因此,我不会包括它们。
与您的问题无关,但是关于您的Monadic代码的一些评论:
每次写
之类的东西do x <- e return x
可以用
e
替换。每次写
之类的东西do e
可以用
e
替换。