Haskell HTTP响应中ByteStrings的Clumsy Looking Type签名 [英] Clumsy Looking Type Signature for ByteStrings in Haskell HTTP Response
问题描述
#!/ 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< - simpleHttphttp://www.stackoverflow.com
return resp
我从这篇文章,我应该更喜欢将响应作为ByteString传递给[Char]或String。我认为OverloadedStrings编译指示可能会减少这个问题,但是就我的out-type而言似乎没有改变。
该函数可以正常工作,为SO的主页提供一个简单的http响应,但是这种类型的签名看起来真的很难看:
getUrl :: IO(Data。 ByteString.Lazy.Internal.ByteString)
我不得不说我看到很少这样的东西互联网的例子(我们有更多的点比椭圆的Java导入,人)。是对的吗?如果我想返回一个响应然后开始解析它,用HXT或tagsoup或attoparsec说,这是正确的方法还是类型签名?
我注意到,对于例如,当我开始添加接受参数的能力时,例如提供不同的URL,这会变得更加丑陋:
import Network .HTTP.Conduit
导入Data.ByteString.Lazy.Internal
- 好的,第一个arg现在是我的url的字符串...
getUrl :: String - > IO(Data.ByteString.Lazy.Internal.ByteString)
getUrl url = do
resp< - simpleHttp url
return resp
main: :IO(ByteString) - 什么?!在 - 的里面 () ?
main = do
getUrlhttps://www.stackoverflow.com
<这似乎是不健康的。我应该如何理解如何正确地构造它?
您始终可以使用其合格路径编写类型。但是,因为您已经导入 Data.ByteString.Lazy.Internal
,除非您有其他 ByteString
键入(如严格的那样),你可以简单地省略 Data.ByteString.Lazy.Internal
:
getUrl :: IO ByteString
另外,除非您有特别需要导入内部
,我建议您只导入 Data.ByteString.Lazy
(它也会导出懒惰 ByteString
你正在使用的类型)。如果你在范围内同时拥有严格和懒惰的 ByteString
,我会将它们导入为合格:
导入符合条件的Data.ByteString作为BS
导入符合条件的Data.ByteString.Lazy作为BL
然后 BS.ByteString
是严格的类型, BL.ByteString
懒惰的 - 无需编写出完整的 Data.ByteString.ByteString
或 Data.ByteString.Lazy.ByteString
。
值得一提的是(谢谢@duplode)任何一个字节串模块通常都是最好的导入限定符,因为它们定义了一系列与Prelude(以及相互之间)冲突的函数。
最后,请注意围绕某个类型的parens本身没有任何作用。 (ByteString)
和 ByteString
是相同的。因此,我不会包含它们。
与您的问题无关,但对您的monadic代码有一些评论: p>
-
每当你写出类似于
do x < - e
return x
e
。 -
每当您写出类似于
do e
可以用
e
。
I'm experimenting with the http-conduit library and have this simple example:
#!/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
I understand from this post that I should prefer a response as a ByteString to a [Char] or String. I assumed the OverloadedStrings pragma might make this less of an issue, but doesn't appear to change with respect to my out-type.
The function works fine and dutifully prints out a simple http response for the homepage of SO, but that type signature looks really ugly:
getUrl :: IO (Data.ByteString.Lazy.Internal.ByteString)
And I have to say I see very few things like that from internet examples (we've got more dots than an elliptical Java import, man). Is that right? If I want to return a reponse and then start parsing on it, say with HXT or tagsoup or attoparsec, is this the right approach or type signature?
I notice, for example, this gets even uglier when I start to add the ability to take arguments, such as supplying a different 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"
This seems unwholesome. How should I understand how to structure this correctly?
You can always write types with their qualified path. However, as you've already imported Data.ByteString.Lazy.Internal
and unless you have some other ByteString
type in scope (like the strict one) you can simply omit the Data.ByteString.Lazy.Internal
:
getUrl :: IO ByteString
Also, unless you have some particular need to import Internal
, I recommend you just import Data.ByteString.Lazy
(which also exports the lazy ByteString
type you are using). If you have both strict and lazy ByteString
in scope, I'd import them qualified:
import qualified Data.ByteString as BS
import qualified Data.ByteString.Lazy as BL
Then BS.ByteString
is the strict type and BL.ByteString
the lazy one - no need to write out the full Data.ByteString.ByteString
or Data.ByteString.Lazy.ByteString
.
It is also worth mentioning (thanks @duplode) that either of the bytestring modules is usually best imported qualified since they defines a whole bunch of functions that clash with the Prelude (and with each other).
Finally, note that parens around a type by itself does nothing. (ByteString)
and ByteString
are identical. As such, I would not include them.
Unrelated to your question, but some remarks on your monadic code:
Every time you write something like
do x <- e return x
it can be replace with just
e
.Every time you write something like
do e
it can be replaced with
e
.
这篇关于Haskell HTTP响应中ByteStrings的Clumsy Looking Type签名的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!