Использование Netwire для создания списков значений
Я думаю, что я принципиально не понимаю, как атаковать этот тип проблемы с Netwire:
У меня есть следующий тест-кейс:
Я хотел бы взять строку, разбить ее на строки, напечатать каждую строку и выйти.
Куски, которые мне не хватает:
- Как запретить после значения в начале конвейера, но затем, если это значение будет разделено, а результаты получены позже, не запрещать, пока все эти результаты не будут использованы.
- Как должна выглядеть функция основного цикла
- Если я должен использовать "один раз"
Вот код, который у меня есть:
import Control.Wire
main :: IO ()
main = recur mainWire
recur :: Wire () IO () () -> IO ()
recur a = do
(e,w) <- stepWire a 0 ()
case e of Left () -> return ()
Right () -> recur w
mainWire :: Wire () IO () ()
mainWire = pure "asdf\nqwer\nzxcv"
>>> once
>>> arr lines
>>> fifo
>>> arr print
>>> perform
Это выводит следующее:
"asdf"
и затем выходит. Если я удалю once
, затем программа работает как положено, многократно выводя полный список строк навсегда.
Я хотел бы следующий вывод:
"asdf"
"qwer"
"zxcv"
Я уверен, что мне здесь не хватает интуиции о том, как правильно подойти к этому классу проблем с Netwire.
1 ответ
Примечание. Это для более старой версии netwire (раньше события работали так, как они работают сейчас), поэтому для корректной работы с текущей версией необходим некоторый перевод кода.
Если я вас правильно понял, вам нужен провод, который производит строки строки, а затем запрещает, когда с этим покончено? Сложно сказать.
once
как следует из названия, производит ровно один раз, а затем тормозит навсегда. Опять же, немного неясно, что делают ваши провода (потому что вы не сказали нам), но это не то, что вы обычно кладете в свой "основной" провод (до сих пор я когда-либо использовал только once
с andThen
).
Если это правильно, я бы, вероятно, сделал что-то вроде:
produceLines s = produceLines' $ lines s where
produceLines' [] = inhibit mempty
produceLines' (l:ls) = pure s . once --> produceLines' ls
(Вы могли бы написать это как фолд или что-то вроде того, я просто подумал, что это немного яснее).
-->
хорош для andThen
если ты не знал По сути, это разбивает переданную строку на строки и превращает их в провод, который производит первую строку один раз, а затем ведет себя как аналогичный провод, за исключением того, что первый элемент удален. Это блокирует неопределенно, как только все значения были произведены.
Это то, что вы хотели?
Обновить
Я вижу, что вы пытались сделать сейчас.
Провод, который вы пытались написать, можно сделать как
perform . arr print . fifo . ((arr lines . pure "asdf\nqwer\nzxcv" . once) --> pure [])
Часть в скобках производят ["adf","nqwer","nzxc"]
на одно мгновение, а затем производит [] навсегда. fifo берет значения из предыдущего проводника, добавляя результат из предыдущего проводника в каждом случае (из-за этого мы должны продолжать производить []). Остальное, как вы знаете (я использую функциональную нотацию, а не стрелку, потому что я предпочитаю, но это не должно быть проблемой для вас).