我正在使用管道库,需要将 ByteString 流转换为行流(即String
),使用 ASCII 编码。我知道还有其他库(Pipes.Text 和 Pipes.Prelude)也许可以让我更轻松地从文本文件中生成行,但是由于其他一些代码,我需要能够将行获取为String
来自制作人ByteString
.
更正式地说,我需要转换Producer ByteString IO ()
to a Producer String IO ()
,产生线条。
我确信这对于经验丰富的管道程序员来说一定是一句简单的话,但到目前为止我还没有成功破解所有的FreeT
and Lens
- Pipes-ByteString 中的诡计。
任何帮助深表感谢!
Stephan
如果您需要该类型签名,那么我建议这样做:
import Control.Foldl (mconcat, purely)
import Data.ByteString (ByteString)
import Data.Text (unpack)
import Lens.Family (view)
import Pipes (Producer, (>->))
import Pipes.Group (folds)
import qualified Pipes.Prelude as Pipes
import Pipes.Text (lines)
import Pipes.Text.Encoding (utf8)
import Prelude hiding (lines)
getLines
:: Producer ByteString IO r -> Producer String IO (Producer ByteString IO r)
getLines p = purely folds mconcat (view (utf8 . lines) p) >-> Pipes.map unpack
这是有效的,因为类型purely folds mconcat
is:
purely folds mconcat
:: (Monad m, Monoid t) => FreeT (Producer t m) r -> Producer t m r
... 在哪里t
在这种情况下将是Text
:
purely folds mconcat
:: Monad m => FreeT (Producer Text m) r -> Producer Text m r
任何时候你想减少每一个Producer
a 的子群FreeT
-您可能想要使用的分隔流purely folds
。然后只需选择正确的即可Fold
减少子组。在这种情况下,您只想连接所有Text
组内的块,所以你传入mconcat
。我通常不建议这样做,因为它会在极长的行上中断,但您指定需要这种行为。
这是冗长的原因是因为pipes
生态系统促进Text
over String
并试图鼓励处理任意长的队伍。如果您不受其他代码的限制,那么更惯用的方法就是:
view (utf8 . lines)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)