在haskell-pipes中分流流动流 [英] Forking the streaming flow in haskell-pipes

查看:83
本文介绍了在haskell-pipes中分流流动流的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我无法通过haskell-pipes来管理流水线。基本上,我分析了一堆文件,然后我必须以人性化的方式将结果打印到终端上 >

  • 将结果编码为JSON

  • 所选路径取决于命令行选项。

    在第二种情况下,我必须输出一个前括号,然后输入每个输入值,后跟一个逗号,然后输入一个右括号。目前 insertCommas 永不终止,因此不会输出右括号。

     导入管道
    导入Data.ByteString.Lazy为B
    导入Data.Aeson(编码)

    insertCommas :: Consumer B.ByteString IO()
    insertCommas = do先
    < - 等待
    抬起$ B.putStr首先
    for cat $ \obj - >提升$ do
    putStr,
    B.putStr obj

    jsonExporter :: Consumer(FilePath,AnalysisResult)IO()
    jsonExporter = do
    lift $ putStr[
    P.map encode> - > insertCommas
    lift $ putStr]

    exportStream :: Config - > Consumer(FilePath,AnalysisResult)IO()
    exportStream conf =
    case outputMode conf
    JSON - > jsonExporter
    _ - > P.map(export conf)> - > P.stdoutLn

    main :: IO()
    main = do
    - 前两行是Docopt的东西,不相关
    args< - parseArgsOrExit模式=<< getArgs
    ins < - allFiles $ args`getAllArgs`参数paths
    let conf = readConfig args
    runEffect $ each ins
    > - > P.mapM分析
    > - > P.map(filterResults conf)
    > - > P.filter filterNulls
    > - > exportStream conf


    解决方案

    我认为你应该'管道' -组。它有一个插入,但不是散布者,但是写出来并不是什么大不了的事。我认为,您应该远离消费者端,以解决这类问题。

      { - #LANGUAGE OverloadedStrings# - } 
    导入管道
    导入合格的Pipes.Prelude作为P
    导入合格的Data.ByteString.Lazy.Char8作为B
    导入Pipes.Group
    导入Lens.Simple - 或Control.Lens或Lens.Micro或任何视图/ ^。
    import System.Environment

    intersperse_ :: Monad m => a - >制片人a m r - > Producer amr
    intersperse_ a producer = intercalates(yield a)(producer ^。chunksOf 1)

    main = do
    args< - getArgs
    let op prod =
    json的案例参数:_ - >产量[*> intersperse_,prod< * yield]
    _ - > intersperse_prod
    runEffect $ op生产者> - > P.mapM_ B.putStr
    putStrLn
    其中
    producer = mapM_ yield(B.wordsthis is a test)

    给我这个

     >>> :main json 
    [this,is,a,test]
    >>> :main ---
    这是一个测试


    I'm having trouble directing flow though a pipeline with haskell-pipes. Basically, I analyze a bunch of files and then I have to either

    1. print results to the terminal in a human-friendly way
    2. encode results to JSON

    The chosen path depends upon a command line option.
    In the second case, I have to output an opening bracket, then every incoming value followed by a comma and then a closing bracket. Currently insertCommas never terminates, so the closing bracket is never outputted.

    import Pipes
    import Data.ByteString.Lazy as B
    import Data.Aeson (encode)
    
    insertCommas :: Consumer B.ByteString IO ()
    insertCommas = do
        first <- await
        lift $ B.putStr first
        for cat $ \obj -> lift $ do
            putStr ","
            B.putStr obj
    
    jsonExporter :: Consumer (FilePath, AnalysisResult) IO ()
    jsonExporter = do
        lift $ putStr "["
        P.map encode >-> insertCommas
        lift $ putStr "]"
    
    exportStream :: Config -> Consumer (FilePath, AnalysisResult) IO ()
    exportStream conf =
        case outputMode conf of
          JSON -> jsonExporter
          _    -> P.map (export conf) >-> P.stdoutLn
    
    main :: IO ()
    main = do
        -- The first two lines are Docopt stuff, not relevant
        args <- parseArgsOrExit patterns =<< getArgs
        ins  <- allFiles $ args `getAllArgs` argument "paths"
        let conf = readConfig args
        runEffect $ each ins
                 >-> P.mapM analyze
                 >-> P.map (filterResults conf)
                 >-> P.filter filterNulls
                 >-> exportStream conf
    

    解决方案

    I think you should 'commify' with pipes-group. It has an intercalates, but not an intersperse, but it's not a big deal to write. You should stay away from the Consumer end, I think, for this sort of problem.

    {-#LANGUAGE OverloadedStrings #-}
    import Pipes
    import qualified Pipes.Prelude as P
    import qualified Data.ByteString.Lazy.Char8 as B
    import Pipes.Group
    import Lens.Simple  -- or Control.Lens or Lens.Micro or anything with view/^.
    import System.Environment
    
    intersperse_ :: Monad m => a -> Producer a m r -> Producer a m r
    intersperse_ a producer = intercalates (yield a) (producer ^. chunksOf 1) 
    
    main = do 
      args <- getArgs
      let op prod = case args of 
            "json":_ -> yield "[" *> intersperse_ "," prod <* yield "]"
            _        -> intersperse_ " " prod
      runEffect $ op producer >-> P.mapM_ B.putStr
      putStrLn ""
      where 
        producer = mapM_ yield (B.words "this is a test")
    

    which give me this

        >>> :main json
        [this,is,a,test]
        >>> :main ---
        this is a test
    

    这篇关于在haskell-pipes中分流流动流的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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