Re[14]: Inline records
От: Temoto  
Дата: 11.01.10 13:55
Оценка:
T>>Это лечение симптомов, а не проблемы. "Костыль".
L>А у меня вот не получается в одном неймспейсе определить несколько классов с одним именем. Приходится по разным разносить — это костыль?

Это толстый тролль. Тут даже отвечать ничего не надо.

Может быть, по-вашему, несколько одинаковых имён для частей типа (record syntax) в разных типах это нонсенс, вы так не пишете и разнести по разным модулям (только из-за ограничений языка) — не чуждо вашей природе. Моей чуждо. Это что-то типа могут ли люди с полностью одинаковыми ФИО сесть в одно такси. Редко встречается и когда произойдёт, они просто сядут в разные, никаких проблем. Но осадок остаётся, логики не видно.
Re[12]: Inline records
От: Temoto  
Дата: 11.01.10 13:58
Оценка:
T>>Нет, я использую только first, а должен писать "_" на каждую часть типа FIO, которую я *не использую*. <-- Внимание, плохо пахнет.

L>
L>foo ComplexRecord{recField=var} = doSomethingWith var
L>


Да с рекордами, кроме уникальности полей всё хорошо, они проблему нескольких "_" решают и просто foo = doSomethingWith $ recField.
Re[15]: Inline records
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 12.01.10 14:14
Оценка:
Здравствуйте, Temoto, Вы писали:

T>Может быть, по-вашему, несколько одинаковых имён для частей типа (record syntax) в разных типах это нонсенс, вы так не пишете и разнести по разным модулям (только из-за ограничений языка) — не чуждо вашей природе. Моей чуждо. Это что-то типа могут ли люди с полностью одинаковыми ФИО сесть в одно такси. Редко встречается и когда произойдёт, они просто сядут в разные, никаких проблем. Но осадок остаётся, логики не видно.


Это не "часть типа" (record syntax — всего лишь сахар), а полноценная функция. В Haskell строгая типизация, для ad-hoc полиморфизма есть классы типов. Моя аналогия с классами подчёркивает именно этот факт. Что ты пытаешься сказать своей?
Re[16]: Inline records
От: Temoto  
Дата: 12.01.10 14:54
Оценка:
T>>Может быть, по-вашему, несколько одинаковых имён для частей типа (record syntax) в разных типах это нонсенс, вы так не пишете и разнести по разным модулям (только из-за ограничений языка) — не чуждо вашей природе. Моей чуждо. Это что-то типа могут ли люди с полностью одинаковыми ФИО сесть в одно такси. Редко встречается и когда произойдёт, они просто сядут в разные, никаких проблем. Но осадок остаётся, логики не видно.

L>Это не "часть типа" (record syntax — всего лишь сахар), а полноценная функция. В Haskell строгая типизация, для ad-hoc полиморфизма есть классы типов. Моя аналогия с классами подчёркивает именно этот факт. Что ты пытаешься сказать своей?


Именно эта "полноценность", то есть, что эта функция находится в глобальном namespace и есть проблема.

Имеется тип
data Maybe a = Just a | Nothing
. Значение Just 3, лично я, рассматриваю, как две части, несущие отдельную информацию. Just (как и Nothing) несёт информацию о том, что это значение типа Maybe. 3 это вторая часть значения, несёт отдельную информацию.

Теперь рассмотрим гипотетический тип
data FIO = FIO { first :: String, last :: String }
. Значение FIO "vasya" "pupkin" я рассматриваю, как состоящее из трёх частей. И функция first — это getter второй части ("vasya"). Если вы согласны с такими терминами, объясните, какой смысл в глобальном getter-е, который работает с одним конкретным типом. Вот если б можно было делать оверлоадинг по типам, т.е. first FIO и first BIO это разные функции, тогда проблемы нет.

Где тут не подходит аналогия с классами. В том, что классы типов вроде как глобальная вещь. Если что-то сравниваемо, то оно Eq. Если из чего-то можно взять часть с именем first, то оно может быть FIO, может быть тысячей других типов.

Возможно, вы имели в виду другое. Вы пишете свой класс JSON, я пишу свой, у нас разное видение методов, которые он должен содержать. Действительно, не получится нам жить в одном неймспейсе, увышка. Но по-моему, разница с record syntax здесь очевидна. То есть глобальность классов гораздо более логична, чем глобальность getter-ов record-ов.
Re[17]: Inline records
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 12.01.10 15:56
Оценка:
Здравствуйте, Temoto, Вы писали:

T>Теперь рассмотрим гипотетический тип
data FIO = FIO { first :: String, last :: String }
. Значение FIO "vasya" "pupkin" я рассматриваю, как состоящее из трёх частей. И функция first — это getter второй части ("vasya"). Если вы согласны с такими терминами, объясните, какой смысл в глобальном getter-е, который работает с одним конкретным типом. Вот если б можно было делать оверлоадинг по типам, т.е. first FIO и first BIO это разные функции, тогда проблемы нет.


Потому что я не рассматриваю его как getter, который не существует без некоего объекта. Потому что для меня это полноценный гражданин, а не его пальто. Вряд ли мне потребуется функция, которая работает одинаково и с FIO и с BIO, т.к. first у них ну очень разные операции, и использовать я их буду в разных местах. Именно поэтому и называться у меня они будут по-разному.

T>Где тут не подходит аналогия с классами. В том, что классы типов вроде как глобальная вещь. Если что-то сравниваемо, то оно Eq. Если из чего-то можно взять часть с именем first, то оно может быть FIO, может быть тысячей других типов.


В случае (==) семантика одна для разных типов, это сравнение, что такое first для FIO, и что он для Pair/List/BIO? Это разные вещи. И называться они должны по разному. Что такое map first?

T>Возможно, вы имели в виду другое. Вы пишете свой класс JSON, я пишу свой, у нас разное видение методов, которые он должен содержать. Действительно, не получится нам жить в одном неймспейсе, увышка. Но по-моему, разница с record syntax здесь очевидна. То есть глобальность классов гораздо более логична, чем глобальность getter-ов record-ов.


У записей нет геттеров, забудь ОО.
У классов нет методов, забудь ОО.

Глобальность классов самих по себе не важна. Важна глобальность перегружаемых функций. Аналогично глобальности меток для полей записи (а не геттеров).

Ещё аналогия

class Named n where
    type E n
    first :: n -> E n
    last :: n -> E n

class CanSetFirst c where
    type F c 
    first :: c -> F c -> c


Две функции с одним именем и разной семантикой. В разных классах. Что изменится, если мы поместим их в разные записи?

Подчеркну, я понимаю твою точку зрения. Но она идёт от ОО. А на Haskell не нужен ОО-дизайн.

На этот счёт было много разговоров (сходу вспоминается extensible records), но пока в Haskell ничего не изменили. По мне, так если каким либо образом метки вынесут из неймспейса функций, то это будет очень неверный шаг.
Re[18]: Inline records
От: Temoto  
Дата: 12.01.10 16:27
Оценка:
T>>Где тут не подходит аналогия с классами. В том, что классы типов вроде как глобальная вещь. Если что-то сравниваемо, то оно Eq. Если из чего-то можно взять часть с именем first, то оно может быть FIO, может быть тысячей других типов.

L>В случае (==) семантика одна для разных типов, это сравнение, что такое first для FIO, и что он для Pair/List/BIO? Это разные вещи. И называться они должны по разному. Что такое map first?


map first непонятно что. Почему? Потому что first в глобальном пространстве имён. map FIO.first (любые вариации типа map FIO $ first, map first $> FIO, неважно) это понятно что такое.

T>>Возможно, вы имели в виду другое. Вы пишете свой класс JSON, я пишу свой, у нас разное видение методов, которые он должен содержать. Действительно, не получится нам жить в одном неймспейсе, увышка. Но по-моему, разница с record syntax здесь очевидна. То есть глобальность классов гораздо более логична, чем глобальность getter-ов record-ов.


L>У записей нет геттеров, забудь ОО.


Это не ОО, это что-то из common sense, просто я использовал термин из ОО. Геттер это функция, которая читает часть сложного значения. Вся разница с ООП только в синтаксисе. Там x.first, а тут first x. Просто в ООП геттер ещё и в другом неймспейсе.

L>У классов нет методов, забудь ОО.


Это опять не из ОО, это официальная хацкельская терминология.

L>Глобальность классов самих по себе не важна. Важна глобальность перегружаемых функций. Аналогично глобальности меток для полей записи (а не геттеров).


L>Ещё аналогия

[...]
L>Две функции с одним именем и разной семантикой. В разных классах. Что изменится, если мы поместим их в разные записи?

Да-да! Вот если б точно такая же перегрузка была бы и для записей — всё было бы шоколадно. Подозреваю, что для этого record syntax должен прозрачно генерить класс на каждый тип записи, и, наверное, это дорого.

L>Подчеркну, я понимаю твою точку зрения. Но она идёт от ОО. А на Haskell не нужен ОО-дизайн.


Может быть я себя обманываю, но мне кажется, что она не идёт от ОО. Я не хочу Java классов, методов объектов, public/private и пр.

L>На этот счёт было много разговоров (сходу вспоминается extensible records), но пока в Haskell ничего не изменили. По мне, так если каким либо образом метки вынесут из неймспейса функций, то это будет очень неверный шаг.


Ясно, спасибо.
Re[19]: Inline records
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 13.01.10 08:29
Оценка:
Здравствуйте, Temoto, Вы писали:

T>map first непонятно что. Почему? Потому что first в глобальном пространстве имён. map FIO.first (любые вариации типа map FIO $ first, map first $> FIO, неважно) это понятно что такое.


А, понял теперь о чём ты. Такого предложения я не слышал. Придётся всегда рядом с first писать FIO? Чем это отличается от fioFirst?

T>Это опять не из ОО, это официальная хацкельская терминология.


Да, сорри.

T>Да-да! Вот если б точно такая же перегрузка была бы и для записей — всё было бы шоколадно. Подозреваю, что для этого record syntax должен прозрачно генерить класс на каждый тип записи, и, наверное, это дорого.


Такое предложение было. Можно реализовать на TH.

T>Может быть я себя обманываю, но мне кажется, что она не идёт от ОО. Я не хочу Java классов, методов объектов, public/private и пр.


Это хорошо.
Re[19]: Inline records
От: Mr.Cat  
Дата: 13.01.10 08:42
Оценка:
Здравствуйте, Temoto, Вы писали:
T>Это не ОО, это что-то из common sense, просто я использовал термин из ОО. Геттер это функция, которая читает часть сложного значения. Вся разница с ООП только в синтаксисе. Там x.first, а тут first x. Просто в ООП геттер ещё и в другом неймспейсе.
Какие еще записи? АТД! И разбирать их паттерн-матчингом, никаких геттеров.
Re[20]: Inline records
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 13.01.10 09:39
Оценка:
Здравствуйте, Mr.Cat, Вы писали:

MC>Какие еще записи? АТД! И разбирать их паттерн-матчингом, никаких геттеров.


Проблема в том, что некоторые АТД содержат много полей.
Re[20]: Inline records
От: Temoto  
Дата: 13.01.10 12:25
Оценка:
T>>map first непонятно что. Почему? Потому что first в глобальном пространстве имён. map FIO.first (любые вариации типа map FIO $ first, map first $> FIO, неважно) это понятно что такое.

L>А, понял теперь о чём ты. Такого предложения я не слышал. Придётся всегда рядом с first писать FIO? Чем это отличается от fioFirst?


Повторением "fio" в определении типа.

data LongType = Constructor { longtypeFirst::String, longtypeBob::Int }
Re[21]: Inline records
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 14.01.10 09:39
Оценка:
Здравствуйте, Temoto, Вы писали:

L>>А, понял теперь о чём ты. Такого предложения я не слышал. Придётся всегда рядом с first писать FIO? Чем это отличается от fioFirst?


T>Повторением "fio" в определении типа.


T>
T>data LongType = Constructor { longtypeFirst::String, longtypeBob::Int }
T>


Это не проблема, префиксы делают маленькими — ltFirst, ltBob. Разницы же в использовании не будет (LongType.First vs longTypeFirst).

Как раз сейчас в haskell-cafe очередное обсуждение этой темы

http://www.mail-archive.com/haskell-cafe@haskell.org/msg69969.html

Рекомендую не заморачиваться. Реального выигрыша не будет, т.к. это даже не ad-hoc полиморфизм — не будет общих функций, работающих над обоими first. Код не уменьшится.
Re[21]: Inline records
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 14.01.10 09:43
Оценка:
Здравствуйте, Temoto, Вы писали:

Вот один из пропозалов TypeDirectedNameResolution.
Я помню, наткнувшись на него, поморщился и забыл.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.