Здравствуйте, EvilChild, Вы писали:
VD>>C# не является линивым, и является императивным. В нем вычисления и так импереативныи и последоательны. Монады ему ныжны как рыбе зонтик.
EC>
EC>Language Integrated Query (LINQ) is a framework that is rooted
EC>in the theoretical ideas of monads and monad comprehensions to
EC>allow seamless querying over objects, XML, and relational data.
Здравствуйте, BulatZiganshin, Вы писали:
BZ>т.е. как видите монада используется сначала для перебора значений в некотором источнике, а затем для отсеивания тех, которые нас не устраивают, при этом описание перебираемого набора и условий отбора коструируется последовательно, предложение за предложением. в linq, как я понимаю, используется что-то похожее, и его операции — это statement'ы монады, перебирающие источник данных или отсекающие ненужные значения. не знаю, правда, как group by в это вписан
Замечательно. Но причем тут монады? Это проблемы реализации императивных алгоритмов на Хаскеле. Таких проблем ни в одном ООЯ нет в помине, так как в них есть объекты с изменяемым состаянием.
Здравствуйте, VladD2, Вы писали:
VD>Замечательно. Но причем тут монады? Это проблемы реализации императивных алгоритмов на Хаскеле. Таких проблем ни в одном ООЯ нет в помине, так как в них есть объекты с изменяемым состаянием.
VD>Теперь перечитай еще раз бредовый лозунг EvilChild-а: VD>LINQ это монады для мейнстрима.
Здравствуйте, VladD2, Вы писали:
EC>>В буквальном смысле (если брать за определение реализацию в Haskell) конечно нет, но идея оттуда. EC>>Я не ожидал, что будут читать буквально. EC>>Исходный смысл моего поста в том, что монады штука не безполезная и LINQ тому подтверждение.
VD>Монад нет в C#, так как они на фиг не упали в ООЯ. Эта сущьность нужна только чтобы убрать идеологические проблемы ленивого, "чистого" ФЯ.
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, BulatZiganshin, Вы писали:
BZ>>т.е. как видите монада используется сначала для перебора значений в некотором источнике, а затем для отсеивания тех, которые нас не устраивают, при этом описание перебираемого набора и условий отбора коструируется последовательно, предложение за предложением. в linq, как я понимаю, используется что-то похожее, и его операции — это statement'ы монады, перебирающие источник данных или отсекающие ненужные значения. не знаю, правда, как group by в это вписан
VD>Замечательно. Но причем тут монады? Это проблемы реализации императивных алгоритмов на Хаскеле. Таких проблем ни в одном ООЯ нет в помине, так как в них есть объекты с изменяемым состаянием.
Монада — это контейнерный тип данных, который представляет собой экземпляр класса Monad,
так же это экземпляр класса Functor, который декларирует наличие одной функции высшего порядка, преобразующей значения в контейнере в соответствии с некоторой функцией.
Как видишь довольно общая идея, применение которой можно найти не только в Haskell.
Механизмы LINQ (трансформация одной последовательности в другую) ложаться в её рамки,
а то, о чём ты говоришь не более чем частные случаи.
EC>Как видишь довольно общая идея, применение которой можно найти не только в Haskell. EC>Механизмы LINQ (трансформация одной последовательности в другую) ложаться в её рамки, EC>а то, о чём ты говоришь не более чем частные случаи.
Народ, не тратьте силы понапрасну.
Здравствуйте, EvilChild, Вы писали:
EC>Т.е., по твоему, не в чистом ФЯ от них толку нет?
Тольку мало. Они вносят оверхед, трудны для понимания и грязны с теоретической точки зрения (должны выполняться законы, которые не проверить автоматически). Из-за возможности создать неправильную монадуу компилятор не может провести оптимизацию, исходя из общих монадических законов.
EC>>Т.е., по твоему, не в чистом ФЯ от них толку нет?
Q>Тольку мало. Они вносят оверхед, трудны для понимания и грязны с теоретической точки зрения (должны выполняться законы, которые не проверить автоматически). Из-за возможности создать неправильную монадуу компилятор не может провести оптимизацию, исходя из общих монадических законов.
в хаскеле они тожде не являются частью языка, и для них нет автооптимизаций, связанных с выполнением этих законов. какой удар!
Здравствуйте, Quintanar, Вы писали:
EC>>Т.е., по твоему, не в чистом ФЯ от них толку нет?
Q>Тольку мало. Они вносят оверхед, трудны для понимания и грязны с теоретической точки зрения (должны выполняться законы, которые не проверить автоматически). Из-за возможности создать неправильную монадуу компилятор не может провести оптимизацию, исходя из общих монадических законов.
А какие им есть альтернативы в случае чистого ФЯ? Кроме Uniqueness Typing из Clean?
Здравствуйте, BulatZiganshin, Вы писали:
BZ>в хаскеле они тожде не являются частью языка, и для них нет автооптимизаций, связанных с выполнением этих законов. какой удар!
1) В Хаскеле есть типы классов. Без них монады практически бесполезны.
2) Специальная поддержка в GHC есть.
3) Монады все равно даже в GHC вносят тормоза. Бесплатно ничего не бывает.
Здравствуйте, Quintanar, Вы писали:
BZ>>в хаскеле они тожде не являются частью языка, и для них нет автооптимизаций, связанных с выполнением этих законов. какой удар!
Q>1) В Хаскеле есть типы классов. Без них монады практически бесполезны. Q>2) Специальная поддержка в GHC есть.
Речь о do нотации? Q>3) Монады все равно даже в GHC вносят тормоза. Бесплатно ничего не бывает.
Можно подробнее?
Еще забыл добавить — монады антифункциональны. Меня крайне раздражала эта их черта в Хаскеле — как будто не на красивом ФЯ пишешь, а на кривой императивной приблуде. Кстати, ленивые вычисления и монадно-императивный подход не очень-то совместимы.
Здравствуйте, EvilChild, Вы писали:
Q>>2) Специальная поддержка в GHC есть. EC>Речь о do нотации?
Да.
Q>>3) Монады все равно даже в GHC вносят тормоза. Бесплатно ничего не бывает. EC>Можно подробнее?
Скажем, монада, которая имитирует исключения с помощью Nothing/Just. Понятно, что руками писать все эти проверки не надо, но на деле они все равно есть. Исключения, очевидно, работали бы в разы эффективнее и в GHC их таки добавили.
Ну и в целом. Каждая монадная операция — это вызов bind. По коду с виду может быть все красиво, а bind в это время будет отжирать ресурсы — в parsec, вроде, такая проблема.
Самый главный аргумент против — это то, что при интенсивном применении монад код становится императивным и по сути и по виду. Это не может не бесить.
Здравствуйте, Quintanar, Вы писали:
Q>Скажем, монада, которая имитирует исключения с помощью Nothing/Just. Понятно, что руками писать все эти проверки не надо, но на деле они все равно есть. Исключения, очевидно, работали бы в разы эффективнее и в GHC их таки добавили. Q>Ну и в целом. Каждая монадная операция — это вызов bind. По коду с виду может быть все красиво, а bind в это время будет отжирать ресурсы — в parsec, вроде, такая проблема.
Речь об этом (страница 7 последний абзац)?
Q>Самый главный аргумент против — это то, что при интенсивном применении монад код становится императивным и по сути и по виду. Это не может не бесить.
Почему по сути?
BZ>>в хаскеле они тожде не являются частью языка, и для них нет автооптимизаций, связанных с выполнением этих законов. какой удар!
Q>1) В Хаскеле есть типы классов. Без них монады практически бесполезны. Q>2) Специальная поддержка в GHC есть. Q>3) Монады все равно даже в GHC вносят тормоза. Бесплатно ничего не бывает.
первое. монады — это класс Monad, реализуемый в бибилиотеке. написать его может любой желающий, а для monad transformers сейчас вообще две разных библиотеки. поддержка их в языке сводится к правилам трансляции do notation. поддержка в компиляторе — куда значительней. во-первых, function guard компилируется в код, использующий монаду. во-вторых, тип "a-> IO b" на самом деле означает "a -> RealWorld -> (# RealWorld, b #)" и ghc предоставляет оптимизацию представления тпов, делающую её эквивалентной "a->b". что кстати говоря и позволяет объявить например "tell :: Int -> IO Int" хотя в девичестве он имеет тип "int(int)" или что-то типа того. однако это оптимизации универсальные и применяются точно так же к любым unboxed tuple и вероятно любому другому фантомному типу
IO & ST monads, таким образом, тормозов не вносят, а остальные — да. это ж в конце концов просто syntax sugar для скрытной передачи параметров никаких проверок/использований соблюдения monad laws нет и в помине, monadic code после desugaring компилируется как любой другой DSL
BZ>>но ведь именно на это соображение я выше и ответил! представь себе скажем имя лог-файла, которое нужно передавать во все процедуры, поскольку запись в лог-файл может понадобиться где-то в самом низу иерархзии вызовов
VD>Представил. Теперь потрудись объяснить причем тут C#?
VD>В нем есть только два способа передать информацию — это глобальные переменные, и параметры методов. VD>Ничего нового в C# 3.0 в этом плане не появится.
самое смешное, что в хаскеле — тоже для записи императивных алгоритмов в pure & lazy языке типа хаскела и clean используется фиктивное значение типа real world, передаваемое в и возвразаемое любой императивной процедурой. оно передаётся по цепочке от порцедуры к процедуре, и таким образом компилятор думает, что все эти процедуры можно вызывать только последовательно, в явно заданном порядке (а кодлогенератор в то же самое время думает, что real world — это туфта, и при генерации кода его просто не замечает). вот смотри, если полностью рассахарить эту IO monad:
main realworld0 = let (rw1,ch1) = getChar realworld0
(rw2,ch2) = getChar rw1
(rw3,()) = putChar rw2 ch1
in (rw3,())
этот код читает два символа и затем выводит второй из них. но второй вызов getChar невозможно опустить, поскольку для вызова putChar требуется "состояние мира". которое может возвратить только он собственно, unique types в clean — это то же самое, с явным заданием каждого "мира", получаемого и возвращаемого каждым вызовом. но используя функции высшего порядка, можно от этого избавиться:
а do предоставляет для этого синтаксический сахар с закосом под императивные языки:
main = do ch1 <- getChar
ch2 <- getChar
putChar ch1
т.е. обратите внимание, что do-нотация чисто синтаксически транслируется в эту последовательность вызовов >>=
а теперь представьте, что вы делаете другую монаду, где вместо передачи туда-сюда фиктивного realworld передаётся что-то существенное, типа хендла этого лог-файла. явно этот вездессущий параметр упоминаться при вызовах не будет, но при этом прекрасно повсюду дойдёт. а для его использования нужно добавить пару операций, специфичных для этой монады (это монада State), которые позволяют читать и изменять её текущую невидимую переменную. представили?
а дальше идут monad transformers, которые представляют не просто одну монаду, а способ добавить к монаде новую функциональность. т.е. ввам не придётся например выбирать между Error monad (прекразает вычисление при возбуждении ошибки), State monad, Parsing monad (сохраняет текущее состояние бибилиотеки парсинга), а вы их можете объединить вместе, наслоив одну на другую и использовать всю необходимую вам функциональность в общем коде. более того, вы можете добавить в этот бутерброд новые монады по мере развития программы, а эта запись do с вызываемыми в ней процедурами останется неизменной
я кстати слышал о реализации энтузиастами монад для питона и схемы. так что возможно. но конечно использовать их там, как и в C* — не фунт изюму
ps: более подробно реализация IO monad описана в http://haskell.org/haskellwiki/IO_inside . один преподаватель колледжа даже говорил, что использует этот текст в своих курсах
Здравствуйте, VladD2, Вы писали:
VD>Нет это их смысл. А вот области применения определяются этим смыслом.
Ну, кроме как посоветовать пойти почитать какие бывают монады мне больше нечего добавить.
VD>В общем, приведи плиз пример где в ООЯ были бы нужны монады.
Давай начну с отмазок — я не говорил, что они нужны в ООЯ, мало того, я даже не говорил, что они в ФЯ нужны :)
Но раз ты сказал волшебное слово...
Монады можно использовать, например, в качестве альтернативы известным паттернам проектирования. Например, вместо NullObject можно взять мейби-монаду. У этого подхода есть определенные преимущества перед NullObject (впрочем, как и недостатки). В частности, нам не нужен отдельный нуль-объект.
Да, и когда будешь отвечать на этот пример, вспомни, пожалуйста, что я не говорил, что монады "нужны", чтобы мы тут не нафлеймили (а то в последнее время у нас это здорово получается). Но вот обосновать их применение, наверное, можно. Раз уж люди их применяют.
Здравствуйте, AndrewVK, Вы писали:
L>>SelectMany == bind, имхо, остальные операторы тоже представляют собой монадические комбинаторы.
AVK>И при чем тут LINQ? SelectMany это просто статический метод в классе Sequence. То что он extension method, это просто синтаксический сахар.
Не понял претензии... А bind это просто метод в классе Monad.
AVK>Вобщем, идея о том, что LINQ это монады на мой вкус кажется крайне странной.
Я воспринял это как взгляд Erik Meijer. Почему бы и нет? Связка есть, монадические законы выполняются.
Здравствуйте, EvilChild, Вы писали:
EC>Т.е., по твоему, не в чистом ФЯ от них толку нет?
Ни малейшего! Это фиговый листок позволяющий сделать вид, что язык действительно чисто-функциональный и ленивый в то время как мир с которым общается язык является императивным.
Та фразу что ты увидил, но не смог осознать, говорила о том, что натолкнуло на мысль запроса по объектам. С тем же успехом их могло натолкнуть на эту мысль что угодно. Просто люди варятся в своих мирах и черпают вдохновение из своих конекстов.
К сведению, в Лиспе похожие запросы были уже много лет.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.