Jes*_*wak 1 post haskell functional-programming network-programming http
我正在尝试学习如何使用Haskell通过HTTP/POST发送简单的字符串http-conduit(以便它也适用于https),从文件中读取目标URL,但对我来说似乎仍然有点压倒性.
基本上相当于我在这里学习使用Racket: 在Racket中发送HTTP POST
有人可以给我一个小的或最基本的例子吗?
当然!这里奇怪的Haskell事情是Haskell的记录系统.当您parseUrl使用URL字符串进行调用时,http-conduit会返回一条Request记录,其中填写了一些默认值,但库要求您填写其余部分.
例如,parseUrl始终返回一个RequestHTTP方法设置为GET.我们可以通过使用记录更新语法覆盖该值 - 您可以使用新键和值附加花括号.
{-# LANGUAGE OverloadedStrings #-}
module Lib where
import Data.Aeson
import Network.HTTP.Client
buildRequest :: String -> RequestBody -> IO Request
buildRequest url body = do
nakedRequest <- parseRequest url
return (nakedRequest { method = "POST", requestBody = body })
send :: RequestBody -> IO ()
send s = do
manager <- newManager defaultManagerSettings
request <- buildRequest "http://httpbin.org/post" s
response <- httpLbs request manager
let Just obj = decode (responseBody response)
print (obj :: Object)
Run Code Online (Sandbox Code Playgroud)
如果你在GHCi中运行它,你应该能够发送POST到httpbin:
?> :set -XOverloadedStrings
?> send "hello there"
fromList [("origin",String "<snip>")
,("args",Object (fromList []))
,("json",Null)
,("data",String "hello there")
,("url",String "http://httpbin.org/post")
,("headers",Object (fromList [("Accept-Encoding",String "gzip")
,("Host",String "httpbin.org")
,("Content-Length",String "11")]))
,("files",Object (fromList []))
,("form",Object (fromList []))]
Run Code Online (Sandbox Code Playgroud)
您还需要OverloadedStrings扩展.没有它,会发生两件事:
nakedRequest { method = "POST" }不会进行类型检查,因为库的预期,一个(严格)ByteString从bytestring库.默认情况下,"POST"所有字符串文字都有类型Stringaka [Char].虽然有一个名为packtake String和returns 的函数ByteString,但打开重载字符串要简单得多.编译器会pack代表您自动调用.还有更多的东西; 请参阅Oliver的博客文章了解细节.
另一个不会进行类型检查的表达方式是send "hello there".send期待一个RequestBody.而且有一个函数在某个地方有类型String -> RequestBody,更容易打开重载的字符串并让编译器为你调用它.