как помириться с IO
Nov. 27th, 2012 08:28 amОказывается, не так просто отказаться от ООП мировосприятия. Что больше всего раздражало, так это отсутствие у IO всяких "getter и setter". Нет, ну, правда: как может что-то заниматься полезным вычислением, если ему нельзя ничего set и даже нельзя ничего get? Как можно общаться с функциями, результат которых (IO a), если потом "из" (IO a) ничего нельзя вынуть?
А вот и не нужно ничего ниоткуда вынимать! Нужно этому IO сказать, что делать! А как же результат, даже результат не отдаст? Дык, не отдаст, если не вам это положено. Односторонняя такая связь. Асинхронная? Асинхронная!
Вот именно, что List да Maybe преподносятся таким образом, будто это контейнеры с удобными ручками. Если рассматривать с т.з. ООП, то чуда особенно и не видно. Ну, контейнер, ну, структура у него private и никак извне не доступна, ну, параметризовали эту private часть "генериком" - эка невидаль. А вот нифига это не контейнеры.
Если хотите, у IO всё настолько private, что нельзя узнать вообще ничего. И тем не менее, можно задать собственные вычисления. Просто нужно перестать думать "дай x, дай y, я тебе верну x*y", а нужно думать "возьми x, возьми y, и вычисли x*y". И нужно перестать думать, куда результат денется - за ним придут.
А вот и не нужно ничего ниоткуда вынимать! Нужно этому IO сказать, что делать! А как же результат, даже результат не отдаст? Дык, не отдаст, если не вам это положено. Односторонняя такая связь. Асинхронная? Асинхронная!
Вот именно, что List да Maybe преподносятся таким образом, будто это контейнеры с удобными ручками. Если рассматривать с т.з. ООП, то чуда особенно и не видно. Ну, контейнер, ну, структура у него private и никак извне не доступна, ну, параметризовали эту private часть "генериком" - эка невидаль. А вот нифига это не контейнеры.
Если хотите, у IO всё настолько private, что нельзя узнать вообще ничего. И тем не менее, можно задать собственные вычисления. Просто нужно перестать думать "дай x, дай y, я тебе верну x*y", а нужно думать "возьми x, возьми y, и вычисли x*y". И нужно перестать думать, куда результат денется - за ним придут.
do x <- xs return $ f x- это совсем не "get x из xs, set f x". Это "у вас там внутри есть x, так примените к нему f". x в данном месте всего-лишь placeholder аргумента, чтобы был ясен его тип и происхождение. Потому как у IO нет способа get x из xs. Есть только способ завернуть в монаду f.
no subject
Date: 2013-06-21 06:56 am (UTC)когда понял, ничего особенного, конечно. но способ вычислений необычный.
no subject
Date: 2013-06-21 07:25 am (UTC)способ "передать полученный результат дальше" необычный. без функций высшего порядка не реализовать.
no subject
Date: 2013-06-21 08:27 am (UTC)что программисты сплошь и рядом рассуждают понятиями "бегун передал палочку другому бегуну"? не думаю, что это так.
что можно рассуждать понятиями "бегун передал палочку другому бегуну", а не функторами? а никто и не заставляет.
no subject
Date: 2013-06-21 09:08 am (UTC)no subject
Date: 2013-06-21 10:19 am (UTC)Передавайте себе объекты на здоровье. Дальше-то что? Но зато если рассматривать этот процесс как передачу в функцию функции (в таблице виртуальных методов объекта), то есть, как функцию высшего порядка, появляются новые возможности - мы теперь можем рассуждать о композиции функций (в терминах ООП не объяснишь, что это такое вообще - ну или вы сейчас скажете, что можно; я предлагаю попробовать) и о сохранении композиции (т.е. функтор).
no subject
Date: 2013-06-21 12:15 pm (UTC)важное свойство вычислений. Объясняет какие трубы и как должны соединяться.
"не доходит - какую воду в ступе толкут"
извините, ничем помочь не могу.
no subject
Date: 2013-06-21 12:39 pm (UTC)Если вы видите прок в типизации аргументов функции, то вы на правильном пути. А так кого-то и джаваскрипт устраивает.
"проблемы поставить не в состоянии"
На "то есть" я не ведусь. Книжки есть.
no subject
Date: 2013-06-21 12:59 pm (UTC)no subject
Date: 2013-06-21 12:21 pm (UTC)no subject
Date: 2013-06-21 12:48 pm (UTC)Примерно так: в разных классах (потому что по-другому нет способа) объявляете методы:
public Pipeline[Decoded] decode(Pipeline[Http] e)
public Pipeline[Encoded] encode(Pipeline[Decoded] p)
public Pipeline[BusinessState] transactionState(Pipeline[Encoded] e)
public Pipeline[BusinessState] transaction(Pipeline[BusinessState] state)
Вот чтобы эти методы можно было связать в Chain именно в соответствии с типами. Тогда это будет у вас некое подобие функтора.
Выгоды от такой типизации очевидны.
no subject
Date: 2013-06-21 01:10 pm (UTC)Да. А что, программа умеет сама вместо Http обрабатывать BusinessState?
"глядя на...Потому что там нет такой строгости с типизацией"
Это и объясняет вашу позицию. Спасибо за ваше мнение.
no subject
Date: 2013-06-21 01:30 pm (UTC)странно как-то, что двумя комментами выше вы яростно возражали, что вам ничего не понятно, что строгая типизация вас раздражает и что мне нужно срочно отчитаться о проблеме, решаемой монадами. Если бы вы сразу заявили, что вам и так всё было понятно, то дискуссия даже ещё короче получилась бы.