Комментарии 20
http://horna.org.ua/books/All_About_Monads.pdf
> Abuse of the Continuation monad can produce code that is impossible to understand and maintain.
> Abuse of the Continuation monad can produce code that is impossible to understand and maintain.
Было бы классно, если бы имелся какой-нибудь веб-фреймворк для Haskell, использующий продолжения (Is anyone using delimited continuations to do web development in Haskell?)
Продолжения – шикарная вещь для удобного и быстрого построения веб-логики и интерфейса приложения, сохраняющего состояния. В этом плане себя прекрасно показывает веб-сервер языка Racket.
Продолжения – шикарная вещь для удобного и быстрого построения веб-логики и интерфейса приложения, сохраняющего состояния. В этом плане себя прекрасно показывает веб-сервер языка Racket.
Не могли бы вы пояснить, что такого шикарного предлагают продолжения веб-разработке?
Можно записать логику с показом множества форм как обычную последовательность действий. Примерно так:
Начинаем нечто
call-cc form1
продолжаем имея результаты form1
call-cc form2
продолжаем уже и с form2
framework обеспечивает возврат после form1/form2.
Начинаем нечто
call-cc form1
продолжаем имея результаты form1
call-cc form2
продолжаем уже и с form2
framework обеспечивает возврат после form1/form2.
Понятно.
> на каждую клиентскую сессию в рантайме развешивается некое дерево замыканий и продолжений, которые держат ссылки на различные объекты, не позволяя мусорщику их подчистить.
> мы не можем нарастить производительность системы добавлением нового сервера с балансировкой веб-запросов в кластере. Потому что все запросы клиента в пределах одной пользовательской сессии должны попадать на ту машину, где она была создана.
> на каждую клиентскую сессию в рантайме развешивается некое дерево замыканий и продолжений, которые держат ссылки на различные объекты, не позволяя мусорщику их подчистить.
> мы не можем нарастить производительность системы добавлением нового сервера с балансировкой веб-запросов в кластере. Потому что все запросы клиента в пределах одной пользовательской сессии должны попадать на ту машину, где она была создана.
Не понял. В выражении callCC $ \k -> k (чёнибудь) k имеет тип (a -> Cont r b), то есть возвращает продолжение со входом отличным от чёнибудь. При этом возвращаемое замыканием значение имеет тип Cont r a. То есть тип чёнибудь. Получается что типы построенного с помощью k продолжения и продолжения, которое будет возвращено (пипец, мне бы хоть окурочек от того косяка, что это породил) отличаются. Как такое может получиться?
После прочтения хочется воскликнуть: о Боже, ну зачем так усложнять простую вещь?
Нет. Ну а к чему минус? Вот смотрите, вызовам с продолжениям в руководстве по lisp уделена пара страничек. И этого достаточно, чтобы понять и пользоваться. В Haskell же монады, мозговыворачивательные ограничения на типы и т.д. Какой смысл в этом? Я вот действительно не понимаю. Тем более, что если судить по Real World Haskell это всё нисколько не упрощает программирование, а только запутывает его. So why so overcomplicated?
square_Cont :: Int -> Cont r Int
-- square_Cont x = return (x*x)
square_Cont = return . join (*)
incr_Cont :: Int -> Cont r Int
-- incr_Cont x = return (x+1)
incr_Cont = return . (+1)
func_Cont :: Int -> Cont r Int
{-
func_Cont x = do inc <- incr_Cont x
sq <- square_Cont inc
return sq
-}
func_Cont = (square_Cont =<<) . incr_Cont
> Эта программа вычисляет факториал, и если он оказывается больше 9000, возвращает сообщение «OVER 9000», а если нет, то просто его значение.
Эта программа возвращает строку «OVER 9000» для n > 7, а для остальных n возвращает строку с n!..
foo :: Int -> Cont r String
foo s = do (i, back) <- getCC' s
when (i < 20) $ back (i*2)
return $ show i
А зачем тут String?
Что такое getCC' и откуда?
Как я вижу, Вы сделали некоторые функции короче. Конечно можно и так, но цель моего «развёрнутого» кода в том, что можно проследить взаимосвязь между использованием продолжений как обычных функций, и как монад.
Сравните:
Да, эта программа не учитывает само значение факториала, просто для n>7 факториал больше 9000.
String тут потому, что в конце мы возвращаем show i, т.е. строковое представление числа.
getCC' — это вариант getCC, с помощью которого можно ещё и передать состояние. Грубо говоря, getCC' возвращает нам пару из текущего состояния вычисления (число в данном случае) и функции, которая берёт новое состояние и возвращает вычисление в заданную точку (как goto). В статье есть больше про getCC и getCC' + объяснение как они работают.
Сравните:
func_cps :: Int -> (Int -> r) -> r
func_cps x k = incr_cps x $ \inc ->
square_cps inc $ \sq ->
k sq
иfunc_Cont :: Int -> Cont r Int
func_Cont x = do inc <- incr_Cont x
sq <- square_Cont inc
return sq
Да, эта программа не учитывает само значение факториала, просто для n>7 факториал больше 9000.
String тут потому, что в конце мы возвращаем show i, т.е. строковое представление числа.
getCC' — это вариант getCC, с помощью которого можно ещё и передать состояние. Грубо говоря, getCC' возвращает нам пару из текущего состояния вычисления (число в данном случае) и функции, которая берёт новое состояние и возвращает вычисление в заданную точку (как goto). В статье есть больше про getCC и getCC' + объяснение как они работают.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Продолжения в Haskell