这个问题有点含糊,但如果您正在寻找基于先前解析的结果控制管道中的操作的示例,则 netstring 协议的实现可能就足够了:
#!/usr/bin/env stack
-- stack --resolver lts-10.3 script
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE OverloadedStrings #-}
import Conduit
import Data.ByteString (ByteString)
import Data.Word8 (_colon, _comma, _0, _9, Word8)
import Control.Exception.Safe (throwString)
netstring :: forall m. MonadThrow m => ConduitM ByteString ByteString m ()
netstring = do
len <- takeWhileCE (/= _colon) .| foldMCE addDigit 0
mchar1 <- headCE
case mchar1 of
Just c
| c == _colon -> return ()
| otherwise -> throwString $ "Didn't find a colon: " ++ show c
Nothing -> throwString "Missing colon"
takeCE len
mchar2 <- headCE
case mchar2 of
Just c
| c == _comma -> return ()
| otherwise -> throwString $ "Didn't end with a comma: " ++ show c
Nothing -> throwString "Missing trailing comma"
where
addDigit :: Int -> Word8 -> m Int
addDigit total char
| char < _0 || char > _9 = throwString "Invalid character in len"
addDigit total char = return $! total * 10 + fromIntegral (char - _0)
main :: IO ()
main = do
let bs = "5:hello,6: world,"
res <- runConduit
$ yield bs
.| ((,) <$> (netstring .| foldC) <*> (netstring .| foldC))
print res