标签: haskell-pipes

导管上游类型参数的真正好处是什么?

我试图理解管道概念的不同实现之间的差异.导管管道之间的区别之一是它们如何将管道熔合在一起.管道

(>+>) :: Monad m
      => Pipe l a b r0 m r1 -> Pipe Void b c r1 m r2 -> Pipe l a c r0 m r2
Run Code Online (Sandbox Code Playgroud)

(>->) :: (Monad m, Proxy p)
      => (b' -> p a' a b' b m r) -> (c' -> p b' b c' c m r) -> c' -> p a' a c' c m r
Run Code Online (Sandbox Code Playgroud)

如果我理解正确,使用管道,当两个管道的任何管道停止时,返回其结果而停止另一个.使用导管,如果左侧管道完成,其结果将向下游发送到右侧管道.

我想知道, …

haskell conduit haskell-pipes

10
推荐指数
2
解决办法
344
查看次数

使用Pipes.Aeson在Haskell中流式解析JSON

Pipes.Aeson库公开以下函数:

decode :: (Monad m, ToJSON a) => Parser ByteString m (Either DecodingError a)
Run Code Online (Sandbox Code Playgroud)

如果我将evalStateT与此解析器和文件句柄作为参数一起使用,则会从文件中读取单个JSON对象并进行解析.

问题是文件包含几个对象(所有类型都相同),我想在阅读时折叠或缩小它们.

Pipes.Parse提供:

foldAll :: Monad m => (x -> a -> x) -> x -> (x -> b) -> Parser a m b
Run Code Online (Sandbox Code Playgroud)

但是你可以看到这会返回一个新的解析器 - 我想不出提供第一个解析器作为参数的方法.

看起来Parser实际上是StateT monad变换器中的Producer.我想知道是否有一种从StateT中提取Producer的方法,以便evalStateT可以应用于foldAll Parser,以及解码Parser中的Producer.

这可能完全是错误的方法.

我的问题,简而言之:
使用Pipes.Aeson解析文件时,折叠文件中所有对象的最佳方法是什么?

parsing json haskell aeson haskell-pipes

9
推荐指数
1
解决办法
853
查看次数

Pipes.Binary.decode - StateT用于什么?

我正在尝试使用管道和基于它构建的各种库来编写基本的网络服务器.预期的流程是:

从socket接收字节串 - >使用二进制解码 - >服务器逻辑在这里 - >发送响应到套接字

我认为这将是:

fromSocket s 4096 >-> decode >-> serverLogic >-> toSocket s
Run Code Online (Sandbox Code Playgroud)

管道二进制有一个decode和一个decodeMany,但我不确定我理解差异,我不知道如何使用decode.为什么decodeMany将上游管道作为参数而不是用它链接>->?你如何使用decode,StateT我的管道最终应该是什么样的?

haskell haskell-pipes

8
推荐指数
1
解决办法
213
查看次数

如何检测Haskell管道中的最后一个块?

我有一个小的Haskell Pipe打印出它运行了多少次:

counterPipe :: Pipe String String IO r
counterPipe = go 0
  where
    go n = do
      await >>= yield
      let n' = succ n
      liftIO $ putStrLn $ "Chunk " ++ show n'
      go n'
Run Code Online (Sandbox Code Playgroud)

我希望能够在处理完最后一个块后打印出一条消息,并可能执行其他任务.我该怎么做呢?

haskell haskell-pipes

8
推荐指数
1
解决办法
178
查看次数

为什么Haskell管道"使用()来关闭未使用的输入和X(无人居住的类型)以关闭未使用的输出"?

Pipes Tutorial中,它说:

具体类型同义词用于()关闭未使用的输入和X(无人居住的类型)以关闭未使用的输出:

我想了解为什么()X使用它们的方式.为什么不X()的输入和输出?

haskell haskell-pipes

8
推荐指数
1
解决办法
189
查看次数

使用Pipes的简单程序挂起

我有以下程序,在运行时不产生输出runhaskell Toy.hs,而是无限期挂起.根据我的理解,程序应该打印"hi"然后退出.我很感激有关如何调试此类问题的答案和/或建议.我正在使用Github的管道4.0.0(github.com/Gabriel439/Haskell-Pipes-Library).

module Toy where

import Pipes
import Control.Monad.State

type Request = String
type Response = String

serveChoice :: Request -> Server Request Response IO ()
serveChoice = forever go
  where go req = do
        lift $ putStrLn req
        respond req

run :: Monad m => () -> Client Request Response (StateT Int m) ()
run () = do
    request "hi"
    return ()

main :: IO ()
main = evalStateT (runEffect $ hoist lift . serveChoice …
Run Code Online (Sandbox Code Playgroud)

haskell haskell-pipes

7
推荐指数
1
解决办法
256
查看次数

分离数据加载/卸载和处理逻辑

有时需要执行一些复杂的例程来检索或保存正在处理的数据.在这种情况下,人们想要分离数据生成和数据处理逻辑.常见的方法是使用类似iteratee的功能.有很多不错的图书馆:管道,管道等.在大多数情况下,他们会做这件事.但是AFAIK它们(除了,可能是管道)受到处理顺序的限制.

但考虑一个日志查看器示例:人类可能希望随机来回漫步.他也可以放大和缩小.我担心迭代者在这里无能为力.

一个简单的解决方案可能如下所示:

-- True is for 'right', 'up', etc. and vice versa 
type Direction = Bool

class Frame (f :: * -> *) where
  type Dimension f :: *

  type Origin f :: * -> *

  grow', shrink' move' :: Monad m => Dimension f -> Direction -> f a -> m (f a)

  move' dim dir f = grow' dim dir f >>= shrink' dim (not dir)

  liftF' :: (Origin f a -> b) -> f a -> …
Run Code Online (Sandbox Code Playgroud)

haskell haskell-pipes

7
推荐指数
1
解决办法
187
查看次数

为什么`效果'只能密封两个流入,而不是所有的流量?

这是包Effect的官方教程中提供的图表pipes.

 type Effect = Proxy X () () X

  Upstream | Downstream
     +---------+
     |         |
 X  <==       <== ()
     |         |
 () ==>       ==> X
     |    |    |
     +----|----+
          v
          r
Run Code Online (Sandbox Code Playgroud)

由于Effect没有任何数据流,我期待它只是Proxy X X X X,密封所有流量.但相反,它允许两个流入.这有什么特别的原因吗?如果我只是Effect通过签名来编写通常所做的事情Proxy X X X X,它可以完美地传递编译器:

myMonad :: Proxy X X X X IO ()
myMonad = do
    a <- lift $ getLine
    lift $ print a
    return ()
Run Code Online (Sandbox Code Playgroud)

为什么我们不能run这样呢?

haskell haskell-pipes

7
推荐指数
1
解决办法
97
查看次数

如何拥有多种通信类型的管道?

说我有这个代码:

import Control.Monad.State hiding (StateT)
import Control.Proxy

server :: (Proxy p, Monad m) => Int -> Server p Int Bool (StateT Int m) ()
server = runIdentityK loop
    where loop arg = do
        currMax <- lift get
        lift $ put $ max currMax arg
        nextArg <- respond (even arg)
        loop nextArg

client :: (Proxy p, Monad m) => Client p Int Bool m ()
client = runIdentityP loop
    where loop = go 1
          go i = do
            isEven <- request …
Run Code Online (Sandbox Code Playgroud)

haskell haskell-pipes

6
推荐指数
1
解决办法
201
查看次数

管道教程:ListT示例

我试图弄清楚管道教程中提到的一个例子ListT:

import Pipes
import qualified Pipes.Prelude as P

input :: Producer String IO ()
input = P.stdinLn >-> P.takeWhile (/= "quit")

name :: ListT IO String
name = do
    firstName <- Select input
    lastName  <- Select input
    return (firstName ++ " " ++ lastName)
Run Code Online (Sandbox Code Playgroud)

如果运行上面的示例,我们得到如下输出:

>>> runEffect $ every name >-> P.stdoutLn
Daniel<Enter>
Fischer<Enter>
Daniel Fischer
Wagner<Enter>
Daniel Wagner
quit<Enter>
Donald<Enter>
Stewart<Enter>
Donald Stewart
Duck<Enter>
Donald Duck
quit<Enter>
quit<Enter>
>>> 
Run Code Online (Sandbox Code Playgroud)

看起来:

  1. 当你运行它(在ghci上)时,你输入的第一个名字将被绑定,只有第二个名称会改变.我希望两个生产者(定义为Select input)在读取输入时轮流(可能是非确定性的).
  2. 输入 …

haskell haskell-pipes

6
推荐指数
1
解决办法
281
查看次数

标签 统计

haskell ×10

haskell-pipes ×10

aeson ×1

conduit ×1

json ×1

parsing ×1