Język Go ma instrukcję select
, której można użyć do odpytywania wielu kanałów i wykonania określonej czynności w zależności od tego, który kanał jest niepusty.Jak zaimplementować ekwiwalent instrukcji Go's select dla kanałów Haskell STM?
E.g.
select {
case a := <- chanA:
foo(a)
case b := <- chanB:
baz(b)
case c := <- chanC:
bar(c)
}
To będzie czekać, aż albo chanA
, chanB
lub chanC
jest niepusty, to jeśli na przykład chanB
jest niepusty, to odczytać z chanB
i zapisać wynik w b
, następnie zadzwonić baz(b)
. Można także dodać klauzulę default:
, co oznacza, że instrukcja select
nie będzie czekać na kanały i zamiast tego zrobi wszystko, co klauzula default
, jeśli wszystkie kanały są puste.
Jaki byłby najlepszy sposób wdrożenia czegoś takiego dla STM TChan
s w Haskell? Można to zrobić naiwnie za pomocą łańcucha if-else: sprawdzanie, czy każdy z nich ma wartość isEmptyChan
, a jeśli nie jest pusty, to odczytanie go i wywołanie odpowiedniej funkcji lub wywołanie retry
, jeśli wszystkie kanały są puste. Zastanawiałem się, czy nie byłoby bardziej eleganckiego/idiomatycznego sposobu na zrobienie tego?
Uwaga: instrukcja Go może zawierać również instrukcje wysyłania w swoich przypadkach i wypełnia tylko instrukcję wysyłania, jeśli jej kanał jest pusty. Byłoby wspaniale, gdyby ta funkcjonalność również mogła zostać powielona, chociaż nie jestem pewien, czy byłby to elegancki sposób.
jedynie nieznacznie podobne ale coś Właśnie zauważyłem i nie jestem pewien, gdzie ją pisać: nie literówka na stronie w opisie Control.Monad.STM dla retry
:
„Wdrożenie może zablokować wątek aż pewnego z telewizyjnych, które przeczytał, został udpated. "
Możesz chcieć spojrzeć na 'r ace' z 'Control.Concurrent.Async'. –
Warto zauważyć, że funkcja go nie wykonuje pierwszej dostępnej akcji, ale jest dostępna, wybrana losowo. To nie będzie głodować kanałów tylko dlatego, że są zdefiniowane później lub pecha na ścieżce wyboru. – Dustin
Jest to całkowicie odmienne od "wybierz" Go. Kanały w Go są ograniczone, w przeciwieństwie do 'TChan' (dzięki czemu są rzeczywiście użyteczne), a' select' może być używane z operacjami wysyłania. – rightfold