Advertisement
Guest User

Untitled

a guest
Aug 15th, 2019
151
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. Чтобы закончить наш курс ярко, предлагаем вам с помощью этой задачи в полной мере почувствовать на себе всю мощь continuation-passing style. Чтобы успешно решить эту задачу, вам нужно хорошо понимать, как работает CPS и монада ContT (а этого, как известно, никто не понимает). Кстати, это была подсказка.
  2.  
  3. Сопрограмма (корутина, coroutine) это обобщение понятия подпрограммы (по-простому говоря, функции). У функции, в отличие от сопрограммы, есть одна точка входа (то, откуда она начинает работать), а точек выхода может быть несколько, но выйти через них функция может только один раз за время работы; у сопрограммы же точек входа и выхода может быть несколько. Проще всего объяснить на примере:
  4.  
  5. coroutine1 = do
  6.   tell "1"
  7.   yield
  8.   tell "2"
  9.  
  10. coroutine2 = do
  11.   tell "a"
  12.   yield
  13.   tell "b"
  14.  
  15. GHCi> execWriter (runCoroutines coroutine1 coroutine2)
  16. "1a2b"
  17.  
  18. Здесь используется специальное действие yield, которое передает управление другой сопрограмме. Когда другая сопрограмма возвращает управление (с помощью того же yield или завершившись), первая сопрограмма продолжает работу с того места, на котором остановилась в прошлый раз.
  19.  
  20. В общем случае, одновременно могут исполняться несколько сопрограмм, причем при передаче управления, они могут обмениваться значениями. В этой задаче достаточно реализовать сопрограммы в упрощенном виде: одновременно работают ровно две сопрограммы и значениями обмениваться они не могут.
  21.  
  22. Реализуйте трансформер CoroutineT, функцию yield для передачи управления и функцию runCoroutines для запуска. Учтите, что одна сопрограмма может завершиться раньше другой; другая должна при этом продолжить работу:
  23.  
  24. coroutine3, coroutine4 :: CoroutineT (Writer String) ()
  25. coroutine3 = do
  26.   tell "1"
  27.   yield
  28.   yield
  29.   tell "2"
  30.  
  31. coroutine4 = do
  32.   tell "a"
  33.   yield
  34.   tell "b"
  35.   yield
  36.   tell "c"
  37.   yield
  38.   tell "d"
  39.   yield
  40.  
  41. GHCi> execWriter (runCoroutines coroutine3 coroutine4)
  42. "1ab2cd"
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement