Язык Go имеет оператор select
, который может использоваться для опроса нескольких каналов и выполнения определенного действия в зависимости от того, какой канал сначала не пуст.
например.
select {
case a := <- chanA:
foo(a)
case b := <- chanB:
baz(b)
case c := <- chanC:
bar(c)
}
Это будет ждать, пока тега chanA
, chanB
или chanC
не будет пуста, тогда если, например, chanB
непустое, оно будет читать из chanB
и сохранить результат в b
, затем вызовите baz(b)
. Предложение default:
также может быть добавлено, что означает, что оператор select
не будет ждать по каналам и вместо этого сделает то, что есть предложение default
, если все каналы пустые.
Каким будет лучший способ реализовать что-то подобное для STM TChan
в Haskell? Это можно было бы сделать наивно цепочкой if-else: проверка, если каждый chan isEmptyChan
, и если он не пуст, а затем считывает его и вызывает соответствующую функцию или вызывает retry
, если все каналы пустые. Мне было интересно, будет ли более элегантный/идиоматический способ сделать это?
Обратите внимание, что оператор Go select
также может включать в себя инструкции отправки в своих случаях и будет заполнять только оператор send, если его канал пуст. Было бы здорово, если бы эта функциональность тоже дублировалась, хотя я не уверен, будет ли элегантный способ сделать это.
Только слегка связанный, но что-то, что я только что заметил, и я не уверен, где его разместить: там есть опечатка на странице Control.Monad.STM в описании для retry
:
"Реализация может блокировать поток до тех пор, пока один из прочитанных ими ТВАР не будет udpated."