Haskell HTTP响应中ByteStrings的Clumsy Looking Type签名 [英] Clumsy Looking Type Signature for ByteStrings in Haskell HTTP Response

查看:166
本文介绍了Haskell HTTP响应中ByteStrings的Clumsy Looking Type签名的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

 #!/ 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆