Сеть нарезает поток байтов на произвольные ByteString
фрагменты. В приведенном выше коде эти фрагменты ByteString
будут сопоставлены с фрагментами Text
, а каждый фрагмент Text
будет проанализирован как decimal
. Однако строка десятичных цифр, представляющая один decimal
, может быть разделена на два (или более) фрагмента Text
. Кроме того, как вы понимаете, использование decimal
возвращает вам оставшуюся часть фрагмента Text
, который не был проанализирован как часть decimal
, который вы пытаетесь вернуть во входной поток.
Обе эти проблемы можно решить, используя Data.Conduit.Attoparsec. conduitParserEither
с Data.Attoparsec.Text.decimal
. Обратите внимание, что недостаточно просто проанализировать decimal
; вам также нужно будет обрабатывать какой-то разделитель между decimal
s.
Также невозможно соединить Source
с CL.map
, так как сигнатура типа CL.map
map :: Monad m => (a -> b) -> Conduit a m b
Функция, которую вы передаете map
, получает возможность преобразовать каждый вход a
в один выход b
, а не в поток b
. Для этого вы можете использовать awaitForever
, но вам нужно преобразовать Source
в обычный Producer
с toProducer
, чтобы типы совпадали.
Однако в вашем коде вы пытаетесь отправить ошибки синтаксического анализа вниз по течению как ByteString
, но вывод mySource
как Int
, что является ошибкой типа. Вы должны предоставить поток ByteString
в обоих случаях; успешный случай синтаксического анализа может вернуть Conduit
, созданный путем слияния других Conduit
, если он заканчивается выходом ByteString
:
...
$= (let f (Left err) = yield $ S8.pack $ "Error: " ++ show err
f (Right (_, i)) = toProducer (mySource i) $= someOtherConduit
in awaitForever f)
где someOtherConduit
погружает Int
из mySource
и создает ByteString
.
someOtherConduit :: Monad m => Conduit Int m ByteString
Наконец, я полагаю, вы хотели подключить snk
в конце трубы вместо src
.
person
pat
schedule
27.11.2017
conduit
отправку данных вверх по течению? Я знаю, чтоpipes
знает. Возможно, вам нужно будет использоватьpipes
для вашего варианта использования. - person Cactus   schedule 30.03.2016Conduit
может поместить данные обратно на свой вход с помощьюleftover
, но здесьConduit
хочет поместить данные обратно на вход вышестоящегоConduit
, что невозможно. В этой ситуации следует использовать парсерConduit
. - person pat   schedule 28.11.2017