我有一个功能f :: ByteString -> String
,需要一个Sink ByteString (ResourceT IO)
。 我如何得到这个?将功能提升到导管槽
不幸的是,该文档是不是非常有帮助?
我有一个功能f :: ByteString -> String
,需要一个Sink ByteString (ResourceT IO)
。 我如何得到这个?将功能提升到导管槽
不幸的是,该文档是不是非常有帮助?
我不知道为什么你需要什么在这个管道做resourceT。
为了将它全部返回到由所有小字节串组成的一个大字符串中,您必须累积片段一段时间,然后将其返回到最后。
fSink :: Monad m => Sink ByteString m String
fSink = go []
where
go accum = do
x <- await
case x of
Nothing -> return . f . B.concat . reverse $ accum
Just x' -> go (x':accum)
谢谢你的回答。对ResourceT的要求仅仅是由于Yesod从版本1.1开始处理文件上传的方式。 你得到一个'Source(ResourceT IO)ByteString'而不是'ByteString',就像它在Yesod 1.0中一样。 – mrueg 2012-08-16 15:08:42
这里是解决问题的通用解决方案:让我们采取任何功能i -> r
,其中i
是Monoid
,并通过与mappend
折叠所有await
S的能把它变成一个水槽。
import Data.Conduit
import Data.Conduit.List as CL
import Data.Monoid
monoidFold :: (Monoid i, Monad m) => (i -> r) -> Sink i m r
monoidFold f = f `fmap` CL.fold mappend mempty
由于ByteString
是Monoid
,您的ByteString -> String
类型的函数可以被用作的monoidFold
参数。
myMD5 :: ByteString -> String
monoidFold myMD5 :: Monad m => Sink ByteString m String
非常有教育意义,谢谢 – fp4me 2012-08-16 18:04:54
你想要接收器做什么? – dave4420 2012-08-16 13:15:31
'Sink ByteString(ResourceT IO)'不是一种类型。你的意思是'Sink ByteString(ResourceT IO)String'? – dave4420 2012-08-16 13:20:09
是的,对不起。接收器应该在Yesod文件上传中使用fileSource的结果,并计算其md5哈希(使用'Yesod.Static.base64md5')。 – mrueg 2012-08-16 15:41:06