Die Go-Sprache hat eine select
-Anweisung, die verwendet werden kann, um mehrere Kanäle abzufragen und eine bestimmte Aktion durchzuführen, je nachdem, welcher Kanal zuerst nicht leer ist.Wie implementieren Sie das Äquivalent von Go's Select-Anweisung für Haskell STM-Kanäle?
z.
select {
case a := <- chanA:
foo(a)
case b := <- chanB:
baz(b)
case c := <- chanC:
bar(c)
}
Dies wird warten, bis entweder chanA
, chanB
oder chanC
nicht leer ist, dann, wenn zum Beispiel chanB
nicht leer ist, ist es aus chanB
und speichert das Ergebnis in b
, dann ruft baz(b)
lesen. Eine default:
-Klausel kann auch hinzugefügt werden, was bedeutet, dass die select
-Anweisung nicht auf die Kanäle wartet und stattdessen die default
-Klausel ausführt, wenn alle Kanäle leer sind.
Was wäre der beste Weg, um so etwas für STM TChan
s in Haskell zu implementieren? Es könnte naiv durch eine if-else-Kette gemacht werden: Überprüfen, ob jeder chan isEmptyChan
, und wenn es nicht leer ist, dann lesen von ihm und die entsprechende Funktion aufrufen, oder sonst retry
aufrufen, wenn alle Kanäle leer sind. Ich habe mich gefragt, ob es eine elegantere/elegantere Art geben würde, dies zu tun?
Beachten Sie, dass die select
-Anweisung von Go auch send-Anweisungen in ihren Fällen enthalten kann und eine send-Anweisung nur vervollständigt, wenn ihr Kanal leer ist. Es wäre großartig, wenn diese Funktionalität auch dupliziert werden könnte, obwohl ich nicht sicher bin, ob es einen eleganten Weg dazu geben würde.
Nur wenig verwandt, aber etwas, das ich gerade bemerkt, und ich bin nicht sicher, wo es schreiben: es auf der Control.Monad.STM Seite in der Beschreibung ein Tippfehler ist für retry
:
„Die Implementierung der Thread, bis ein Block kann von den TVars, die es gelesen hat, war udpated. "
Sie könnten sich "r Ass "aus" Control.Concurrent.Async ". –
Es ist erwähnenswert, dass go nicht die erste verfügbare Aktion ausführt, sondern eine verfügbare, zufällig ausgewählte. Es wird Kanäle nicht verhungern, nur weil sie später oder unglücklich im Auswahlpfad definiert sind. – Dustin
Das ist völlig anders als Gos 'select'. Kanäle in Go sind im Gegensatz zu 'TChan' begrenzt (wodurch sie tatsächlich nützlich sind) und' select' kann mit Sendeoperationen verwendet werden. – rightfold