我在尝试构造 RequestBody ResourceT IO
时遇到问题。
我对管道比较陌生,正在尝试使用 aws
包将文件上传到 S3。
io $ withManager $ \mgr ->
do Aws.pureAws cfg s3cfg mgr $ S3.putObject stcompleted "job.zip" $
RequestBodySourceChunked $ do
CB.sourceFile "job.zip"
我收到的类型错误是这样的。
Couldn't match type `Data.ByteString.Internal.ByteString'
with `Blaze.ByteString.Builder.Internal.Types.Builder'
Expected type: Source
(ResourceT IO) Blaze.ByteString.Builder.Internal.Types.Builder
Actual type: ConduitM
() Data.ByteString.Internal.ByteString (ResourceT IO) ()
In the return type of a call of `CB.sourceFile'
In a stmt of a 'do' block: CB.sourceFile "job.zip"
In the second argument of `($)', namely
`do { CB.sourceFile "job.zip" }'
putObject 的类型是
putObject
:: Bucket
-> Data.Text.Internal.Text
-> http-conduit-1.9.5.2:Network.HTTP.Conduit.Types.RequestBody
(Control.Monad.Trans.Resource.Internal.ResourceT IO)
-> PutObject
我看不到如何构造 RequestBody ResourceT IO,因为 RequestBody 的可能构造函数不包含 ResoureceT IO
data RequestBody m
= RequestBodyLBS Data.ByteString.Lazy.Internal.ByteString
| RequestBodyBS Data.ByteString.Internal.ByteString
| RequestBodyBuilder GHC.Int.Int64
Blaze.ByteString.Builder.Internal.Types.Builder
| RequestBodySource GHC.Int.Int64
(Data.Conduit.Internal.Source
m Blaze.ByteString.Builder.Internal.Types.Builder)
| RequestBodySourceChunked (Data.Conduit.Internal.Source
m Blaze.ByteString.Builder.Internal.Types.Builder)
最佳答案
这里的关键(稍微清理一下)是:
Couldn't match type ByteString with Builder
所以第一个问题是:如何将 ByteString 转换为 Builder? Using Hoogle我们得到了一些可能的命中,并且 fromByteString事实证明是最好的。
下一个问题是如何转换Source
以产生新类型的值。这需要对管道有一定的了解,对此我推荐 the conduit tutorial 。但其想法是创建一个数据转换器(Conduit
),用于转换 ByteString
的传入流并生成 Builder
的输出流,并将其与源
融合。
第一步,我们要使用 Data.Conduit.List
中的 map
抽象。对于第二个,融合运算符是$=
。将所有这些放在一起,我们有:
CB.sourceFile "job.zip" $= Data.Conduit.List.map fromByteString
关于haskell - 使用管道将文件作为 HTTP 请求的源,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21169112/