Re[46]: [haskell] considered mainstream
От: BulatZiganshin  
Дата: 10.03.09 15:55
Оценка:
Здравствуйте, eao197, Вы писали:

E>>>Во-вторых, я не понимаю, почему GC не может вызывать деструкторы у "мусорных" объектов. В Java и C# финалайзеры у объектов вызываются и ничего, все живы-здоровы. А если GC будет вызывать деструкторы, то описанной проблемы не будет в принципе.

Z>>Может, через час. А если нужно детерминированно?

E>Ситуация ничем не будет отличаться от того, что есть в той же Java.


вот поэтому в яве, C#, D — любых языках с GC деструкторы не используются для освобождения *ресурсов*. а у C++ — legacy код
Люди, я люблю вас! Будьте бдительны!!!
Re[45]: [haskell] considered mainstream
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 10.03.09 16:26
Оценка: +1
Здравствуйте, BulatZiganshin, Вы писали:

BZ>соответственно, если добавить GC в С++, то legacy код будет несовместим с ним, поскольку в нём просто отсутствует разделение дестурукторов на освобождение ресурсов и освобождение памяти. т.е. несмотря на GC дестуруркторы всё равно придётся вызывать детерминированно для освобождения ресурсов


Не вижу больших препятствий к тому, чтобы вызывать деструкторы в C++ для тех объектов, которые GC посчитал мусором. Ведь вопрос упирается во что -- без GC утекает память и ресурсы для тех объектов, для которых сейчас пользователь явно не вызвал delete. Добавляется GC с вызовом деструкторов и оказывается, что и память больше не течет, и ресурсы освобождаются. Да, пусть не сразу, пусть через час. Но освобождаются. Это гораздо лучше, чем в случае теперешних утечек.

А если пользователь хочет гарантированно иметь освобождение ресурсов -- пусть и дальше вызывает delete явно. Как это есть сейчас. Так что для нормальных C++ программ вообще ничего не изменится. А у не очень нормальных появится шанс работать стабильнее.


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[41]: [haskell] considered mainstream
От: FR  
Дата: 10.03.09 16:30
Оценка:
Здравствуйте, thesz, Вы писали:

T>Так каких-то лет пять всего.


За пять лет некторые языки устареть успевают

T>>>И требования у тебя выше.

FR>>Так к лучшему из функциональных языков же

T>Так к ещё не развернувшемуся в полную силу.


Ттттормозиттт

T>Это сокращает количество ошибок.


Вот плохой ты евангилист, надо было сразу раскрывать

T>Всякого рода преобразования встречаются и в далёких от ЯП программах. В тех же оптимизаторах файловых систем, ведь файловая система и есть дерево с типами блоков, да ещё и хитро увязанных друг с другом.


T>Почему пишущие на C++ до сих пор не пользуются GADT, мне непонятно.


Ты это осторожней не накаркай, в буст уже почти засунули алгебраические типы


T>Поэтому нужна система типов, которую мы можем затачивать под наши конкретные цели. Система типов Хаскеля движется в этом направлении.


Да интересно, но эту ветку пилят еще метапрограммирование и динамика, так что посмотрим кто кого.

FR>>Там же есть еще другой вывод, очень многие задачи вообще неприводимы и неупрощаемы


T>Essential complexity по Бруксу.


T>Такое встречается очень редко.


Похоже не так уж и редко. И чем дальше в лес тем больше дров.
Re[42]: [haskell] considered mainstream
От: thesz Россия http://thesz.livejournal.com
Дата: 10.03.09 16:38
Оценка:
T>>Это сокращает количество ошибок.
FR>Вот плохой ты евангилист, надо было сразу раскрывать

Так я сразу сказал — "сокращает".

T>>Поэтому нужна система типов, которую мы можем затачивать под наши конкретные цели. Система типов Хаскеля движется в этом направлении.

FR>Да интересно, но эту ветку пилят еще метапрограммирование и динамика, так что посмотрим кто кого.

Динамика не ловит все возможные пути прохода кода и точно не на этапе компиляции. Метапрограммирование само нуждается в многоуровневой системе типов — чтобы глупости не создавало.

А так — да, посмотрим.

FR>>>Там же есть еще другой вывод, очень многие задачи вообще неприводимы и неупрощаемы

T>>Essential complexity по Бруксу.
T>>Такое встречается очень редко.
FR>Похоже не так уж и редко. И чем дальше в лес тем больше дров.

Практически все встречавшиеся мне примеры упрощались сменой подхода.
Yours truly, Serguey Zefirov (thesz NA mail TOCHKA ru)
Re[46]: [haskell] considered mainstream
От: BulatZiganshin  
Дата: 10.03.09 17:36
Оценка: +1
Здравствуйте, eao197, Вы писали:

BZ>>соответственно, если добавить GC в С++, то legacy код будет несовместим с ним, поскольку в нём просто отсутствует разделение дестурукторов на освобождение ресурсов и освобождение памяти. т.е. несмотря на GC дестуруркторы всё равно придётся вызывать детерминированно для освобождения ресурсов


E>Не вижу больших препятствий к тому, чтобы вызывать деструкторы в C++ для тех объектов, которые GC посчитал мусором. Ведь вопрос упирается во что -- без GC утекает память и ресурсы для тех объектов, для которых сейчас пользователь явно не вызвал delete. Добавляется GC с вызовом деструкторов и оказывается, что и память больше не течет, и ресурсы освобождаются. Да, пусть не сразу, пусть через час. Но освобождаются. Это гораздо лучше, чем в случае теперешних утечек.


E>А если пользователь хочет гарантированно иметь освобождение ресурсов -- пусть и дальше вызывает delete явно. Как это есть сейчас. Так что для нормальных C++ программ вообще ничего не изменится. А у не очень нормальных появится шанс работать стабильнее.


ты полагаешь, что GC — это фича для того, чтобы сделать менее заметными баги? и корректные c++ программы им пользщоваться всё равно не должны, даже если он появится? тогда нафига он нужен — рассуждают авторы языка

вообще, сколько можно разжёвывать простейшие вещи. такое впечатление, что вы даже не пытаетесь понять, о чём идёт речь, прдепочитая 100 раз повторять одно и то же, чтобы оставить за собой "поле боя"
Люди, я люблю вас! Будьте бдительны!!!
Re[47]: [haskell] considered mainstream
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 10.03.09 18:01
Оценка:
Здравствуйте, BulatZiganshin, Вы писали:

BZ>ты полагаешь, что GC — это фича для того, чтобы сделать менее заметными баги?


Блин, мне казалось, что пример Java должен был всем это уже давно доказать

BZ> и корректные c++ программы им пользщоваться всё равно не должны, даже если он появится? тогда нафига он нужен — рассуждают авторы языка


Он нужен для того, чтобы сделать жизнь проще. При наличии GC в языке 70% деструкторов можно будет выбросить вообще. При наличии GC в языке многопоточное программирование станет гораздо проще. При наличии GC в языке exception safety будет обеспечиваться на порядки проще. В итоге программы станут компактнее, проще и, временами, быстрее.

Только, имхо, для этого нужно вводить точный GC в язык раз и навсегда. Без оглядки на всякие встраиваемый системы, системы реального времени, high perfomance computing системы и пр. Только вот утопия это все пока.

BZ>вообще, сколько можно разжёвывать простейшие вещи. такое впечатление, что вы даже не пытаетесь понять, о чём идёт речь, прдепочитая 100 раз повторять одно и то же, чтобы оставить за собой "поле боя"


Лично мне не понятно, почему за главную причину невозможности внедрения GC в C++ выдается RAII и наличие деструкторов. В C++ гораздо больше других факторов, препятствующих внедрению GC. Но этого вы даже понять не пытаетесь. Как и объяснить, например, коммерческую невыгодность использования функционального программирования



SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[48]: [haskell] considered mainstream
От: BulatZiganshin  
Дата: 10.03.09 18:13
Оценка:
Здравствуйте, eao197, Вы писали:

E>Лично мне не понятно, почему за главную причину невозможности внедрения GC в C++ выдается RAII и наличие деструкторов.


не наличие дестуркторов. а то, что в одном фрагменте кода делается высвобождение ресурсов и памяти. в результате чего несмотря на наличие GC придётся продолжать явно вызывать деструкторы. и проблема в том, что только 10% классов нуждается в освобождении ресурсов. в языках с GC эти 10% "деструкторов" вызываются явно, с помощью механизмов, аналогичных gc — bracket, using. в C++ приходится вызывать деструкторы для *всех* объектов — на всякий случай, вдруг там ресурсы тоже. и поэтому GC просто собирать нечего — разве что в ошибочных программах
Люди, я люблю вас! Будьте бдительны!!!
Re[48]: [haskell] considered mainstream
От: z00n  
Дата: 10.03.09 18:52
Оценка:
Здравствуйте, eao197, Вы писали:

E>Лично мне не понятно, почему за главную причину невозможности внедрения GC в C++ выдается RAII и наличие деструкторов. В C++ гораздо больше других факторов, препятствующих внедрению GC. Но этого вы даже понять не пытаетесь.


Консервативному GC ничего больше не мешает. Разговор о неконсервативном GC пытаетесь навязать вы — по мне это подмена темы, и в целом мне даже 5-ти минут жалко чтобы помечтать о неконсервативном GC в C++.
Re[49]: [haskell] considered mainstream
От: BulatZiganshin  
Дата: 10.03.09 19:06
Оценка:
Здравствуйте, BulatZiganshin, Вы писали:

BZ>в языках с GC эти 10% "деструкторов" вызываются явно, с помощью механизмов, аналогичных gc — bracket, using


аналогичных RAII, of course
Люди, я люблю вас! Будьте бдительны!!!
Re[48]: [haskell] considered mainstream
От: WolfHound  
Дата: 10.03.09 19:33
Оценка: +2
Здравствуйте, eao197, Вы писали:

E>Только, имхо, для этого нужно вводить точный GC в язык раз и навсегда. Без оглядки на всякие встраиваемый системы, системы реального времени, high perfomance computing системы и пр. Только вот утопия это все пока.

Нет. Это Ява...

А вобще в С++ GC не нужен.
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[49]: [haskell] considered mainstream
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 10.03.09 20:50
Оценка:
Здравствуйте, z00n, Вы писали:

Z>Консервативному GC ничего больше не мешает.


Мешают float-ы и double, которые могут содержать значения, очень похожие на указатели. А так же byte[], которые используются внутри криптографических алгоритмов. Вскоре после выхода D 1.000 на эту проблему указали Брайту и он добавил в std.gc метод hasNoPointers для ручного запрещения GC сканирования областей памяти, содержимое которых может быть похоже на указатель.

Если уж при обсуждении внедрения в C++ консервативного GC обсуждаются проблемы вызова деструкторов применительно к legacy codebase, то почему не принимается во внимание char[], float[] и doible[], которых в том же legacy codebase будет великое множество?


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[50]: [haskell] considered mainstream
От: z00n  
Дата: 10.03.09 21:56
Оценка:
Здравствуйте, eao197, Вы писали:

E>Здравствуйте, z00n, Вы писали:


Z>>Консервативному GC ничего больше не мешает.


E>Мешают float-ы и double, которые могут содержать значения, очень похожие на указатели. А так же byte[], которые используются внутри криптографических алгоритмов.

Если после последующих 4 проверок GC будет продолжать считать что это указатель — утечет немного памяти. Расскажите(в смысле дайте ссылку), кто реально с этим столкнулся и к каким ужасам это привело.

E>Вскоре после выхода D 1.000 на эту проблему указали Брайту и он добавил в std.gc метод hasNoPointers для ручного запрещения GC сканирования областей памяти, содержимое которых может быть похоже на указатель.

Можно ссылку на описание проблемы? По мне — это больше похоже на оптимизацию. Я Брайта понимаю — жалко что ли? — комитет то уламывать не надо.

E>Если уж при обсуждении внедрения в C++ консервативного GC обсуждаются проблемы вызова деструкторов применительно к legacy codebase, то почему не принимается во внимание char[], float[] и doible[], которых в том же legacy codebase будет великое множество?


В ObjectiveC 2.0 уже 3 года как консервативный GC. Tim Sweeney применяет его в UnrealEngine2/3 уже несколько лет на приставках без виртуальной памяти.

Давайте вы дадите ссылки на релевантные документы о проблемах.
Re[51]: [haskell] considered mainstream
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 11.03.09 08:44
Оценка:
Здравствуйте, z00n, Вы писали:

E>>Мешают float-ы и double, которые могут содержать значения, очень похожие на указатели. А так же byte[], которые используются внутри криптографических алгоритмов.

Z>Если после последующих 4 проверок GC будет продолжать считать что это указатель — утечет немного памяти. Расскажите(в смысле дайте ссылку), кто реально с этим столкнулся и к каким ужасам это привело.

http://www.digitalmars.com/d/archives/digitalmars/D/The_problem_with_the_D_GC_46407.html


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[52]: [haskell] considered mainstream
От: z00n  
Дата: 11.03.09 11:28
Оценка:
Здравствуйте, eao197, Вы писали:

Z>>Если после последующих 4 проверок GC будет продолжать считать что это указатель — утечет немного памяти. Расскажите(в смысле дайте ссылку), кто реально с этим столкнулся и к каким ужасам это привело.


E>http://www.digitalmars.com/d/archives/digitalmars/D/The_problem_with_the_D_GC_46407.html

На dmd 1.041 это не воспроизвелось, из чего я делаю вывод, что это просто давно исправленный баг Брайтового велосипеда (интересно, чего он просто не взял Boehm?)
Еще?

PS. Конечно иногда имеет смысл не сканировать некоторые области памяти — все необходимые аннотации в прдложении Боема комитету есть(N2310- ссылку я уже давал)
Re[53]: [haskell] considered mainstream
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 11.03.09 11:41
Оценка:
Здравствуйте, z00n, Вы писали:

E>>http://www.digitalmars.com/d/archives/digitalmars/D/The_problem_with_the_D_GC_46407.html

Z>На dmd 1.041 это не воспроизвелось, из чего я делаю вывод, что это просто давно исправленный баг Брайтового велосипеда (интересно, чего он просто не взял Boehm?)

Эта проблема была исправлена в версии 1.001 через две недели после публикации данного бага:
http://www.digitalmars.com/d/1.0/changelog.html#new1_001:

New type aware GC


Z>PS. Конечно иногда имеет смысл не сканировать некоторые области памяти — все необходимые аннотации в прдложении Боема комитету есть(N2310- ссылку я уже давал)


А кто будет делать аннотации к унаследованному коду?


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[54]: [haskell] considered mainstream
От: z00n  
Дата: 11.03.09 13:05
Оценка:
Здравствуйте, eao197, Вы писали:

E>А кто будет делать аннотации к унаследованному коду?

К унаследованному коду не нужно делать аннотаций — а просто использовать его как есть, без GC. Достаточно очевидно, что GC не ищет указатели в памяти, которую не он выделял.

Для иллюстрации этот пример на С + libgc, он лечится убиранием GC из "Legacy Code".

#include <gc.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
    int data_length = 5000000;
    int i,incoming_length, *incoming;
    
    /* 1 - Legacy Code */
    // int *data = (int*)GC_MALLOC(sizeof(int)*data_length); // <-- Leak
    int *data = (int*)malloc(sizeof(int)*data_length); // <-- OK
    for (i = 0; i < data_length; ++i) 
    {
        data[i] = rand();
    }
    
    /* 2 - New Code */
    for(;;) 
    {
        incoming_length = 1000 + rand()%5000;
        incoming = (int*)GC_MALLOC(sizeof(int)*incoming_length);
        for (i = 0; i < incoming_length; ++i) {
            incoming[i] = rand();
        }
    }
}
Re[30]: [haskell] considered mainstream
От: Klapaucius  
Дата: 11.03.09 14:02
Оценка: 8 (2) +1
Здравствуйте, pgregory, Вы писали:

P>Я в это просто верю.


Этому, конечно, трудно что-то противопоставить.

P>Я предъявляю претензию к языку. Потому, что он заставляет меня знать, что такое монада. Мне это не нравится. Заметьте, хаскель не заставляет знать, что такое коммутативное кольцо, чтобы оперировать числами.


Хаскель в точно такой же степени заставляет знать, что такое монады, в какой он, Питон, Схема, С, etc заставляют знать что такое коммутативное кольцо.

Если не знать что такое коммутативное кольцо с единицей — можно написать, например, b+0, хотя это то же свамое, что и b, а если не знать что такое монады можно написать
a <- foo
return a

хотя это то же самое, что и просто foo.
Писать без понимания монад на Haskell, разумеется, можно, но читать чужой код, по всей видимости, будет трудно.

P>Не знаю, почему, но то, что мне не нравятся сложные языки программирования, некоторые пытаются списать на мою ограниченность, нежелание изучать ничего нового и черт знает что еще.


P>Простота (и красота) — основа всего окружающего мира.


Просто те языки, которые вы считаете сложными, другие считают простыми и наоборот. Так происходит потому, что простой язык — это действительно язык привычный, а сложный — непривычный. Как я уже говорил, интуиция основана на опыте, а потому, знакомый язык — интуитивно понятный, а незнакомый — контринтуитивный. Никаких намеков на огранниченность и антиинтеллектуализм это не содержит, просто мир говорит с нами на том, языке, на котором мы думаем, а потому тот, кто знаком с ООП видит всюду подтвержения его интуитивности. Привычка определяет сознание в такой степени, что спустя годы использования C человек начинает думать, будто бы в школьных учебниках пользовались скобками не только для обозначения приоритета, и, следовательно писали не cos x, а cos(x). Т.е. это привычка делает мир "императивным", а не мир делает императивность привычной. Взгляд на мир меняется, и если роль времени в императивном языке соотвествует роли времени в ньютоновской механике, то роль времени в чистом функциональном языке соотвествует роли времени в ТО — и не зря в SICP проводится аналогия между ленивыми потоками и мировыми линиями, а полная энергия системы в квантовой механике, например, это комбинатор волновых функций.

P>И поэтому я верю, что реально хороший язык реально прост.


Что же касается объективной составляющей сложности, то она ограничена снизу выразительностью языка.
Т.е. невыразительный язык, разумеется, может быть неограниченно сложным, но при определенной выразительности должен иметь сложность не меньше минимальной для такого уровня выразительности.
Фактически, мы меняем сложность языка на простоту текста на этом языке — и реально простой язык не может быть реально хорош, ведь для испольхзования он непригоден.
Например Брейнфак — очень простой язык, который можно выучить за минуту, но он настолько маломощен, что не предоставляет практически никаких средств абстракции и декомпозиции и, следовательно, код на нем чудовищно сложен.
Понятно, что проще всего ничему не учиться и ничего не уметь, но для неумеющего ничего любая задача бесконечно сложна.
... << RSDN@Home 1.2.0 alpha 4 rev. 1110>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Re[28]: [haskell] considered mainstream
От: Klapaucius  
Дата: 11.03.09 14:09
Оценка:
Здравствуйте, eao197, Вы писали:

E>Я в этом сомневаюсь. Может быть, для людей с хорошим математическим и абстрактным мышлением так и было бы, но не для меня.


Вообще-то работа программиста — это оперирование абстракциями, так что для человека пишущего программы, (по всей видимости, не безуспешно) заявлять о плохости своего абстрактного мышления — это какая-то нездоровая скромность. Хотя, конечно, чем лучше — тем лучше — тут поспорить трудно.
... << RSDN@Home 1.2.0 alpha 4 rev. 1110>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Re[30]: [haskell] considered mainstream
От: Klapaucius  
Дата: 11.03.09 14:24
Оценка:
Здравствуйте, pgregory, Вы писали:

P>Да ладно! Законченная-то законченная, только ничего не объясняющая. Иначе все монадные туториалы представляли бы из себя одну-единственную фразу.


Самое сложное в монадах — это монадные туториалы. Я это понял в 2005-ом, кажется, году, когда прочел на этом форуме сообщение, в котором для объяснения монад проводились аналогии с унитарными эволюциями и коллапсом волновой функции.

K>>Целые числа и операции над ними изучают 10 лет, и в том числе изучаются все войства кольца — ведь объяснение кольца должно быть включено в объяснение целых чисел в любом случае. Это-то понятно? Какие из свойств коммутативного кольца с единицей вы не изучали в школе? Разве что только слово "кольцо" не упоминали — вот и все.


P>Это принципиально. Я именно об этом и пишу.

Т.е. узнать все про кольца кроме названия — это не принципиально, а услышать слово "Кольцо" — принципиально?

K>>А все эти группы и кольца изучаются за еденицы академических часов — просто чтобы показать общность свойств разных объектов, которую можно и самому заметить.

K>>С монадами то же самое. Вы утверждаете, что в RWH без привлечения монад ничего не объясняется — но ведь это не правда. Там монады сначала изобретаются трижды — для IO, для Maybe и для парсеров — и только потом эта общность свойств получает название "монада" — именно так это происходит и при изучении чисел и алгебраических структур.

P>Есть большая разница. После окончания нормальной школы, человек может хорошо решать кучу практических задач. При этом, он может ни разу в жизни не слышать о коммутативных кольцах.


Если он умеет считать — все 8 свойств коммутативного кольца с единицей он знает.

P>В случае с хаскелем это неверно. Практически невозможно написать сколько-нибудь нетривиальную программу, не зная, что такое монада. That's the whole point.


В случае с Хаскелем все точно так же, как и с умением считать.

K>>Нет, признан факт, что то, что вам уже известно вы считаете простым, а то, что неизвестно — сложным. Понять что такое Maybe и не понять при этом, что такое монада невозможно, точно также как нельзя научиться считать и при этом не узнать, что a + 0 = a.

P>Ну неужели, печатая это, вы не поймали себя на том, что куда честнее было бы привести аналогию «точно также как нельзя научиться считать и при этом не узнать, что такое коммутативное кольцо с единицей»?!

Еще раз, слов "коммутативное кольцо с единицей" можно не услышать, но все свойства изучаются — если нет — скажите какие.

P>Я просто высказываю свою точку зрения.


Это очевидно.

P>Я не считаю ее единственно правильной.


Что значит "единственно правильной"? Вы допускаете, что ваша точка зрения может быть не одна правильной, а на ряду с ней еще какая-то другая?

P>Хотя и считаю, что у нее есть серьезные обоснования. Время покажет, кто прав. Вы понимаете мою точку зрения?


Полагаю, что да. Но есть серьезные основания считать, что я понимаю ее не так, как понимаете ее вы.

P>Я вашу, думаю, понимаю.


Не уверен.
... << RSDN@Home 1.2.0 alpha 4 rev. 1110>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Re[31]: [haskell] considered mainstream
От: pgregory Россия  
Дата: 11.03.09 16:20
Оценка: :))
Здравствуйте, Klapaucius, Вы писали:

P>>Я предъявляю претензию к языку. Потому, что он заставляет меня знать, что такое монада. Мне это не нравится. Заметьте, хаскель не заставляет знать, что такое коммутативное кольцо, чтобы оперировать числами.


K>Хаскель в точно такой же степени заставляет знать, что такое монады, в какой он, Питон, Схема, С, etc заставляют знать что такое коммутативное кольцо.


K>Если не знать что такое коммутативное кольцо с единицей — можно написать, например, b+0, хотя это то же свамое, что и b, а если не знать что такое монады можно написать

a <- foo
return a

K>хотя это то же самое, что и просто foo.

Вот вы и попались!

Это -- чушь. Доказательство (GHCi, version 6.10.1):

Prelude> let f1 x = do { a <- x; return a }
Prelude> :t f1
f1 :: (Monad m) => m b -> m b

Prelude> let f2 x = x
Prelude> :t f2
f2 :: t -> t

Для разнообразия добавим еще
Prelude> let f3 x = return x
Prelude> :t f3
f3 :: (Monad m) => a -> m a

и
Prelude> let f4 x = do x
Prelude> :t f4
f4 :: t -> t


Сравните с
Prelude> let b = 0
Prelude> :t b + 0
b + 0 :: Integer
Prelude> :t b
b :: Integer


Комментарии нужны?

Да, я понимаю, что вы хотели сказать. Но, как видите, у вас не получилось :-)
--
In code we trust.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.