Рассмотрите следующий код Erlang:
-module(testit).
-export([testit/0]).
testit() ->
Pid = spawn(fun testit_proc/0),
Pid ! final,
Pid ! one,
Pid ! two,
io:format("Root finished~n").
testit_proc() ->
receive
one -> io:format("One~n");
two -> io:format("Two~n")
end,
receive
one -> io:format("One~n");
two -> io:format("Two~n")
end,
receive
one -> io:format("One~n");
two -> io:format("Two~n");
final -> io:format("Final~n")
end,
io:format("Spawn finished~n").
Вывод:
Root finished
One
Two
Final
Spawn finished
Обработка final
сообщение по существу задерживается, пока последние не получают блок на основании предыдущего, получают шаблоны, не соответствующие тому сообщению.
Как дела это с TChan Haskell?
Вы имеете в виду функцию выборочного приема в Erlang. Насколько мне известно, STM в Haskell не имеет аналогов. Вы можете выбрать либо рефакторинг кода, чтобы устранить необходимость в нем (например, используя отдельные очереди для различных типов информации, которая может быть получена), либо реализовать эту функцию в библиотеке.
Семантика выборочного приема заключается в том, что помимо очереди входящих сообщений у вас также есть список отложенных сообщений. В функции приема вам необходимо сначала просканировать список отложенных сообщений на предмет совпадения сообщений. Если сообщение совпадает, вы удаляете его из списка и доставляете. Если отложенные сообщения не совпадают, вам нужно дождаться сообщения в почтовом ящике. Когда сообщение получено, вы проверяете его соответствие. Если да, то вы доставляете его; если нет, то вы помещаете его в список отложенных и повторяете.