Как сделать Haskell TChan отсроченными сообщениями, такими как очереди сообщений Erlang?

Рассмотрим следующий код 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 по существу отложена до последнего блока приема в силу предыдущих шаблонов приема, не соответствующих этому сообщению.

Как вы это делаете с Haskell TChan?

Ответ 1

Вы имеете в виду функцию выборочного приема Erlang. Насколько я знаю, STM в Haskell не имеет параллели. Ваш выбор состоит в том, чтобы либо реорганизовать ваш код, чтобы удалить его (например, используя отдельные очереди для различных типов информации, которые могут быть получены), либо реализовать эту функцию в библиотеке.

Семантика выборочного приема заключается в том, что помимо очереди входящих сообщений у вас также есть список отложенных сообщений. В функции приема вам нужно сначала отсканировать список отложенных сообщений для любых соответствующих сообщений. Если сообщение соответствует, вы удалите его из списка и доставьте его. Если отложенные сообщения не совпадают, вам нужно дождаться сообщения в папке "Входящие". Когда сообщение получено, вы проверяете, совпадает ли оно. Если это так, то вы его доставляете; если нет, то вы подталкиваете его к отложенному списку и повторяете.