Haskell 如何从导管中读取不同的数据块(例如,直到LF的一条线,然后是10个字节)?

Haskell 如何从导管中读取不同的数据块(例如,直到LF的一条线,然后是10个字节)?,haskell,input,conduit,Haskell,Input,Conduit,对于一个网络协议,我需要能够灵活地从源m ByteString读取不同类型的数据块。有一个linescombinator,它将输入拆分为行,但我需要能够将读取行和固定数量的字节组合起来 我目前的做法是创建一个助手函数: |在输入上折叠给定函数。当函数返回左Left 并将其结果累积到列表中。当函数返回Right时, 连接累加结果(包括最后一个)并返回它, 使用剩余的存储剩余的内容。如果没有输入,则返回Nothing 可用 使用此功能,我可以创建特定的使用者: bytes :: (Monad m)

对于一个网络协议,我需要能够灵活地从
源m ByteString
读取不同类型的数据块。有一个
lines
combinator,它将输入拆分为行,但我需要能够将读取行和固定数量的字节组合起来

我目前的做法是创建一个助手函数:

|在输入上折叠给定函数。当函数返回左
Left
并将其结果累积到列表中。当函数返回
Right
时, 连接累加结果(包括最后一个)并返回它, 使用剩余的
存储剩余的内容
。如果没有输入,则返回
Nothing
可用

使用此功能,我可以创建特定的使用者:

bytes :: (Monad m) => Int -> Consumer ByteString m (Maybe ByteString)
bytes = chunk f
  where
    f n bs | n' > 0     = Left (bs, n')
           | otherwise  = Right $ BS.splitAt n bs
      where n' = n - BS.length bs

line :: (Monad m) => Consumer ByteString m (Maybe ByteString)
line = chunk f ()
  where
    f _ bs = maybe (Left (bs, ()))
                   (\i -> Right $ BS.splitAt (i + 1) bs)
                   (BS.findIndex (== '\n') bs)

有更好的办法吗?我想这个问题一定已经在某个地方解决了。

看起来很正确,它非常类似于Warp解析请求头的方式,尽管Warp不需要任何高级组合器。

看起来很正确,它非常类似于Warp解析请求头的方式,尽管Warp不需要任何高级组合符。

看起来不错,它与Warp解析请求头的方式非常相似,尽管Warp不需要任何高级组合符。@MichaelSnoyman谢谢,也许可以添加它作为答案,这样我就可以接受它了。看起来不错,这与Warp解析请求头的方式非常相似,不过Warp不需要任何更高级别的组合符。@MichaelSnoyman谢谢你,也许可以把它作为一个答案添加进来,这样我就可以接受它了。
bytes :: (Monad m) => Int -> Consumer ByteString m (Maybe ByteString)
bytes = chunk f
  where
    f n bs | n' > 0     = Left (bs, n')
           | otherwise  = Right $ BS.splitAt n bs
      where n' = n - BS.length bs

line :: (Monad m) => Consumer ByteString m (Maybe ByteString)
line = chunk f ()
  where
    f _ bs = maybe (Left (bs, ()))
                   (\i -> Right $ BS.splitAt (i + 1) bs)
                   (BS.findIndex (== '\n') bs)