Re[29]: LINQ только для РСУБД!
От: Геннадий Васильев Россия http://www.livejournal.com/users/gesha_x
Дата: 24.11.09 12:06
Оценка:
Здравствуйте, IT, Вы писали:

IT>Громоздко и некрасиво, особенно, если нужны вложенные функции.


Всё ясно. Да, тут действительно с Linq не понятно, как поступать — разве что, заворачивать запрос в функцию и вызывать эту же функцию из запроса. В принципе, получается то же самое "протягивание" состояния. Может, кстати, lomeo прав насчёт отображения, сохраняющего структуру...
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Re[36]: LINQ только для РСУБД!
От: Gaperton http://gaperton.livejournal.com
Дата: 24.11.09 12:06
Оценка:
Здравствуйте, Lloyd, Вы писали:

>>Первое. Массив доступен глобально, но "состоянием" он не является, именно потому, что он иммутебельный.


L>Почему ты ставишь знак равенства м/у состоянием и мутабельностью? Это разные вещи.

...
L>Состояние != мутабельнсости.

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

G>>Нет, как раз именно это и не является протаскиванием состояния. Протянутое состояние невозможно выразить в терминах comprehensions.


L>Расшифруй.


"Протягивание состояния" — термин, обозначающий общую технику избавления от явного состояния, состоящую в передаче и транформации данных через последовательность вызовов, передаваемых и возвращаемых отдельным параметром через все вызовы.

Простейший пример — у меня есть цикл, который суммирует массив во внутренней мутабельной переменной. Она — является состоянием. Как мне от него избавиться? Преобразовать цикл в рекурсию, и передовать значение текущей суммы через параметр функции. Эта переменная — и есть "протянутое состояние".


[ map( x ) | x <- y, filter( x ) ]

При использовании функций map и filter у тебя нет возможности "протянуть" состояние от вызова к вызову, так как ты не можешь передать его через параметр функции ни в map, ни в reduce. Ты можешь его передать только явно, через мутабельную переменную, что будет явным состоянием. А неизменяемые данные состоянием не являются.

Одним из следствий отсутствия изменяемого состояния является "прозрачность по ссылкам" — независимость результата от порядка вычислений.

G>>Вот если я вместо цикла напишу, например, какой-нибудь foldl, и буду транформировать массив на каждом шаге, передавая его изменения с одной итерации на другую — то это будет оно. Протянутое состояние.


L>Ты именно так и предлагаешь по сути делать. Только это протягивание будет не на этапе fold-а, а переде ним, там где ьы собрался делать склейку. В fold придет уже придет последовательность с нужными данными, но сформированы они как раз будет все через то же протягивание.


Нет, я предлагаю делать совершенно не так. В своем решении я не пользуюсь foldl. Если говорить в терминах функций, оно целиком основано на комбинации map, filter, и функций-генераторах числовых последовательностей. Ни то, ни другое не протягивает состояния.
Re[37]: LINQ только для РСУБД!
От: Lloyd Россия  
Дата: 24.11.09 12:30
Оценка:
Здравствуйте, Gaperton, Вы писали:

L>>Почему ты ставишь знак равенства м/у состоянием и мутабельностью? Это разные вещи.

G>...
L>>Состояние != мутабельнсости.

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


Я вроде и не спорю. Я просто пытаюсь понять, твою логику, понять почему ты ставишь занк равенства между этими понятиями. Но если, не хочешь, не буду настаивать.

G>>>Нет, как раз именно это и не является протаскиванием состояния. Протянутое состояние невозможно выразить в терминах comprehensions.


L>>Расшифруй.


G>

G>"Протягивание состояния" — термин, обозначающий общую технику избавления от явного состояния, состоящую в передаче и транформации данных через последовательность вызовов, передаваемых и возвращаемых отдельным параметром через все вызовы.

G>Простейший пример — у меня есть цикл, который суммирует массив во внутренней мутабельной переменной. Она — является состоянием. Как мне от него избавиться? Преобразовать цикл в рекурсию, и передовать значение текущей суммы через параметр функции. Эта переменная — и есть "протянутое состояние".


Ты избавлялся от состояний и в результате получил "протянутое состояние". Я правильно понимаю, что "протянутое состояние" для тебя состоянием не является?

G>[ map( x ) | x <- y, filter( x ) ]


G>При использовании функций map и filter у тебя нет возможности "протянуть" состояние от вызова к вызову, так как ты не можешь передать его через параметр функции ни в map, ни в reduce. Ты можешь его передать только явно, через мутабельную переменную, что будет явным состоянием. А неизменяемые данные состоянием не являются.


Я приводил пример с методом AttachState. В нем нет изменяемых данных, но есть нечто (у меня оно было названо state), что передается от вызова к вызову и при этом от вызова к вызову меняется. Считаешь ли ты это нечто состоянием или нет?

G>>>Вот если я вместо цикла напишу, например, какой-нибудь foldl, и буду транформировать массив на каждом шаге, передавая его изменения с одной итерации на другую — то это будет оно. Протянутое состояние.


L>>Ты именно так и предлагаешь по сути делать. Только это протягивание будет не на этапе fold-а, а переде ним, там где ьы собрался делать склейку. В fold придет уже придет последовательность с нужными данными, но сформированы они как раз будет все через то же протягивание.


G>Нет, я предлагаю делать совершенно не так. В своем решении я не пользуюсь foldl. Если говорить в терминах функций, оно целиком основано на комбинации map, filter, и функций-генераторах числовых последовательностей. Ни то, ни другое не протягивает состояния.


Ок. С map и filter понятно. Осталось понять что ты называешь функциями-генераторами. Можно привести пример?
Re[38]: LINQ только для РСУБД!
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 24.11.09 12:50
Оценка: 1 (1) +2
Здравствуйте, Lloyd, Вы писали:

L> В нем нет изменяемых данных, но есть нечто, что [...] меняется.


8-0 Это как?

state у тебя меняется явно в определении AttachState. А то, что у тебя при использовании AttachState, так это аргумент и результат функции, они да — неизменны. Например, item в Select тоже меняется

Насчёт состояние == мутабельность, это, конечно, не совсем так, но обычно, когда говорят "состояние" подразумевают именно изменяемое состояние. Обычно мало смысла говорить о неизменяемом состоянии:

const = 5


Глобальная переменная const — неизменяемая. Состояние или нет? Если да, то состояние — это что угодно, если нет, то под глобальным состоянием следует понимать именно изменяемое состояние. Как то так.
Re[38]: LINQ только для РСУБД!
От: Gaperton http://gaperton.livejournal.com
Дата: 24.11.09 12:55
Оценка:
Здравствуйте, Lloyd, Вы писали:

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


L>Я вроде и не спорю.


Если не считать, что ты несколько раз в разных вариантах повторил, что "состояние != мутабельнсости", без каких-либо пояснений, то да — ты не споришь.

L>Я просто пытаюсь понять, твою логику, понять почему ты ставишь занк равенства между этими понятиями. Но если, не хочешь, не буду настаивать.


Ну, я объяснил как мог.

G>>>>Нет, как раз именно это и не является протаскиванием состояния. Протянутое состояние невозможно выразить в терминах comprehensions.


L>>>Расшифруй.


G>>

G>>"Протягивание состояния" — термин, обозначающий общую технику избавления от явного состояния, состоящую в передаче и транформации данных через последовательность вызовов, передаваемых и возвращаемых отдельным параметром через все вызовы.

G>>Простейший пример — у меня есть цикл, который суммирует массив во внутренней мутабельной переменной. Она — является состоянием. Как мне от него избавиться? Преобразовать цикл в рекурсию, и передовать значение текущей суммы через параметр функции. Эта переменная — и есть "протянутое состояние".


L>Ты избавлялся от состояний и в результате получил "протянутое состояние". Я правильно понимаю, что "протянутое состояние" для тебя состоянием не является?


Да, "протянутое состояние" вполне можно назвать состоянием.

G>>[ map( x ) | x <- y, filter( x ) ]


G>>При использовании функций map и filter у тебя нет возможности "протянуть" состояние от вызова к вызову, так как ты не можешь передать его через параметр функции ни в map, ни в reduce. Ты можешь его передать только явно, через мутабельную переменную, что будет явным состоянием. А неизменяемые данные состоянием не являются.


L>Я приводил пример с методом AttachState. В нем нет изменяемых данных, но есть нечто (у меня оно было названо state), что передается от вызова к вызову и при этом от вызова к вызову меняется. Считаешь ли ты это нечто состоянием или нет?


В принципе можно, с некоторой натяжкой. Ты можешь назвать его состоянием, с целью подчеркнуть, что оно "протягивается". И люди тебя в целом поймут.

G>>>>Вот если я вместо цикла напишу, например, какой-нибудь foldl, и буду транформировать массив на каждом шаге, передавая его изменения с одной итерации на другую — то это будет оно. Протянутое состояние.


L>>>Ты именно так и предлагаешь по сути делать. Только это протягивание будет не на этапе fold-а, а переде ним, там где ьы собрался делать склейку. В fold придет уже придет последовательность с нужными данными, но сформированы они как раз будет все через то же протягивание.


G>>Нет, я предлагаю делать совершенно не так. В своем решении я не пользуюсь foldl. Если говорить в терминах функций, оно целиком основано на комбинации map, filter, и функций-генераторах числовых последовательностей. Ни то, ни другое не протягивает состояния.


L>Ок. С map и filter понятно. Осталось понять что ты называешь функциями-генераторами. Можно привести пример?


Конечно. Генератором в comprehensions являются выражения вида (паттерн) <- (выражение, возвращающее множество). К примеру, n <- seq( 1, n, 2) — это генератор.

Функцией-генератором я в данном случае назвал seq( startIdx, endIdx, step ), которая генерирует последовательность индексов начиная со startIdx, не более чем endIdx, с шагом step. В Эрланге этому соответствует именно вызов функции. В Хаскеле/Clean может быть записан как список, что-то вроде [1..n], а при преобразовании comprehensions в циклы — эта штука преобразуется тупо в заголовок цикла for.
Re[30]: LINQ только для РСУБД!
От: IT Россия linq2db.com
Дата: 24.11.09 14:38
Оценка:
Здравствуйте, Gaperton, Вы писали:

G>Я имею в виду не фичи как таковые, а демонстрацию фичи на проблеме, где ее применение действительно мотивированно, и это не вызывает никаких сомнений. Это, естественно сделать гораздо тяжелее, чем рассуждать о тонкостях самой технологии. Ибо речь по сути не об ее устройстве, а об умении ее по делу применять.


Я тебе уже давал ссылку. Вот она
Автор: IT
Дата: 22.09.08
ещё раз.
Если нам не помогут, то мы тоже никого не пощадим.
Re[14]: LINQ только для РСУБД!
От: vdimas Россия  
Дата: 24.11.09 15:15
Оценка:
Здравствуйте, IT, Вы писали:

IT>
IT>int pos = text.Split('\n').Take(line).Sum(s => s.Length + 1) + column;
IT>

IT>Без линка пришлось бы наворачивать циклы и состояния. Это я к вопросу о незначительности решения. И таких упражнений в день у меня по сто штук без всяких баз данных.

Положа руку на сердце, деле класс-расширение Linq.Enumerable к самому Linq постольку-поскольку относится, правильнее было его в какие-нить System.Collections закинуть. А вот аналогичный Linq.Queryable — ему в линке самое место, но ты его в примере не пользуешь.
Re[39]: LINQ только для РСУБД!
От: Lloyd Россия  
Дата: 24.11.09 19:08
Оценка:
Здравствуйте, lomeo, Вы писали:

L>> В нем нет изменяемых данных, но есть нечто, что [...] меняется.


L>8-0 Это как?


L>state у тебя меняется явно в определении AttachState. А то, что у тебя при использовании AttachState, так это аргумент и результат функции, они да — неизменны. Например, item в Select тоже меняется


Нет, для внешнего наблюдателя каждый раз порождается новое состояние на основе старого. Изменения переменных нет.

L>Насчёт состояние == мутабельность, это, конечно, не совсем так, но обычно, когда говорят "состояние" подразумевают именно изменяемое состояние. Обычно мало смысла говорить о неизменяемом состоянии:


Почему?

L>
L>const = 5
L>


L>Глобальная переменная const — неизменяемая. Состояние или нет? Если да, то состояние — это что угодно, если нет, то под глобальным состоянием следует понимать именно изменяемое состояние. Как то так.


Состояние, конечно.
Re[39]: LINQ только для РСУБД!
От: Lloyd Россия  
Дата: 24.11.09 19:15
Оценка:
Здравствуйте, Gaperton, Вы писали:

G>>>>>Нет, как раз именно это и не является протаскиванием состояния. Протянутое состояние невозможно выразить в терминах comprehensions.


L>>>>Расшифруй.


G>>>

G>>>"Протягивание состояния" — термин, обозначающий общую технику избавления от явного состояния, состоящую в передаче и транформации данных через последовательность вызовов, передаваемых и возвращаемых отдельным параметром через все вызовы.

G>>>Простейший пример — у меня есть цикл, который суммирует массив во внутренней мутабельной переменной. Она — является состоянием. Как мне от него избавиться? Преобразовать цикл в рекурсию, и передовать значение текущей суммы через параметр функции. Эта переменная — и есть "протянутое состояние".


L>>Ты избавлялся от состояний и в результате получил "протянутое состояние". Я правильно понимаю, что "протянутое состояние" для тебя состоянием не является?


G>Да, "протянутое состояние" вполне можно назвать состоянием.


Как же так, мы избавлялись от состояния, но оно все равно осталось. К чему было прилагать усилия?

G>>>[ map( x ) | x <- y, filter( x ) ]


G>>>При использовании функций map и filter у тебя нет возможности "протянуть" состояние от вызова к вызову, так как ты не можешь передать его через параметр функции ни в map, ни в reduce. Ты можешь его передать только явно, через мутабельную переменную, что будет явным состоянием. А неизменяемые данные состоянием не являются.


L>>Я приводил пример с методом AttachState. В нем нет изменяемых данных, но есть нечто (у меня оно было названо state), что передается от вызова к вызову и при этом от вызова к вызову меняется. Считаешь ли ты это нечто состоянием или нет?


G>В принципе можно, с некоторой натяжкой. Ты можешь назвать его состоянием, с целью подчеркнуть, что оно "протягивается". И люди тебя в целом поймут.


Но оно же не меняется. Просто на основе старого значения вячисляется новое. Разве не получается, что есть состояние и при этом оно неизменно.

G>>>>>Вот если я вместо цикла напишу, например, какой-нибудь foldl, и буду транформировать массив на каждом шаге, передавая его изменения с одной итерации на другую — то это будет оно. Протянутое состояние.


L>>>>Ты именно так и предлагаешь по сути делать. Только это протягивание будет не на этапе fold-а, а переде ним, там где ьы собрался делать склейку. В fold придет уже придет последовательность с нужными данными, но сформированы они как раз будет все через то же протягивание.


G>>>Нет, я предлагаю делать совершенно не так. В своем решении я не пользуюсь foldl. Если говорить в терминах функций, оно целиком основано на комбинации map, filter, и функций-генераторах числовых последовательностей. Ни то, ни другое не протягивает состояния.


L>>Ок. С map и filter понятно. Осталось понять что ты называешь функциями-генераторами. Можно привести пример?


G>Конечно. Генератором в comprehensions являются выражения вида (паттерн) <- (выражение, возвращающее множество). К примеру, n <- seq( 1, n, 2) — это генератор.


G>Функцией-генератором я в данном случае назвал seq( startIdx, endIdx, step ), которая генерирует последовательность индексов начиная со startIdx, не более чем endIdx, с шагом step. В Эрланге этому соответствует именно вызов функции. В Хаскеле/Clean может быть записан как список, что-то вроде [1..n], а при преобразовании comprehensions в циклы — эта штука преобразуется тупо в заголовок цикла for.


Тогда непонятно как ты будешь "транформировать массив", если ни одна из перечиленных функций не меняет состояния. Как в итоге массив окажется странсформированным?
Re[28]: Кстати
От: VladD2 Российская Империя www.nemerle.org
Дата: 24.11.09 19:18
Оценка: 1 (1) +1
Здравствуйте, Геннадий Васильев, Вы писали:

ГВ>Как это вяжется с тем, что Linq, мол, предназначен для любых источников данных? Получается, что только для тех, которые сводятся к РСУБД-like.


Не к реляционным, а к спискам. Просто спискам. Просто таблицы в РСБУД — это тоже списки кортежей. Вот и все.
Все что может быть представлено в виде списка может быть обработано линком.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[40]: LINQ только для РСУБД!
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 25.11.09 04:28
Оценка: 1 (1) +1
Здравствуйте, Lloyd, Вы писали:

L>Нет, для внешнего наблюдателя каждый раз порождается новое состояние на основе старого. Изменения переменных нет.


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

L>>Глобальная переменная const — неизменяемая. Состояние или нет? Если да, то состояние — это что угодно, если нет, то под глобальным состоянием следует понимать именно изменяемое состояние. Как то так.

L>Состояние, конечно.

Хорошо. У нас есть состояние — все привязки в нашей программе, например, связи фунции с их именами. Какие рассуждения можно вести в терминах понятия "состояние" о программе, учитывая, что оно, а следовательно и поведение программы, неизменно? Какие рассуждения можно получить из понятия "Вселенная" в физике, а не в философии? Т.е. какие полезные рассуждения могут быть проведены?
Re[29]: Кстати
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 25.11.09 04:35
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Не к реляционным, а к спискам. Просто спискам. Просто таблицы в РСБУД — это тоже списки кортежей. Вот и все.

VD>Все что может быть представлено в виде списка может быть обработано линком.

А LINQ работает с деревом?
Если да — from obj in tree select obj.name — вернёт дерево имён или просто список?
Re[22]: LINQ только для РСУБД!
От: Undying Россия  
Дата: 25.11.09 05:32
Оценка: +1 -2
Здравствуйте, IT, Вы писали:

IT>В данном случае простота напрямую зависит от уровня подготовки. Не секрет, что один и тот же код для одного человека может быть простым, а для другого сложным. Это как раз тот самый случай. Вот тут
Автор: IT
Дата: 22.09.08
я давал пример одного и того же алгоритма на Linq и в императивном стиле. Разница очевидна. ФП привносит в код декларативность, а значит простоту и гибкость. Но всё это требует определённой подготовки.


А совмещение императивного и функционального подхода читается еще проще:

    static Dictionary<string, List<Percent>> CalcPercents2(
        ProvidingVolume[] providingVolumes, ReceivingVolume[] receivingVolumes)
    {
      Dictionary<string, List<ProvidingVolume>> providingGroup = new Dictionary<string, List<ProvidingVolume>>();
      foreach (ProvidingVolume pv in providingVolumes)
        providingGroup.GetOrCreateValue(pv.Provider).Add(pv);

      Dictionary<string, List<ReceivingVolume>> receivingGroup = new Dictionary<string, List<ReceivingVolume>>();
      foreach (ReceivingVolume rv in receivingVolumes)
        receivingGroup.GetOrCreateValue(rv.Account).Add(rv);

      Dictionary<string, double> receivingSum = new Dictionary<string, double>();
      foreach (List<ReceivingVolume> list in receivingGroup.Values)
        receivingSum[list[0].Account] = list.Sum(delegate(ReceivingVolume rv) { return rv.Volume; });

      Dictionary<string, List<Percent>> percents = new Dictionary<string, List<Percent>>();
      foreach (List<ProvidingVolume> list in providingGroup.Values)
      {
        double sum = list.Sum(delegate(ProvidingVolume pv) { return pv.Volume; });

        foreach (ProvidingVolume pv in list)
        {
          List<ReceivingVolume> rv = receivingGroup.FindObject(pv.Account);
          if (rv != null)
          {
            foreach (ReceivingVolume r in rv)
            {
              Percent percent = new Percent();
              percent.Provider = pv.Provider;
              percent.Receiver = r.Receiver;
              percent.Account = pv.Account;
              percent.Value = pv.Volume / sum * r.Volume / receivingSum[r.Account];

              percents.GetOrCreateValue(percent.Provider).Add(percent);
            }
          }
        }
      }

      return percents;
    }


Т.к. этот код сравним по лаконичности с чисто функциональным, но при чтении и при отладке элементарно бьется по шагам, а чисто функциональный код приходиться пытаться понять весь целиком, что на порядок сложнее.

        static Dictionary<string, List<Percent>> CalcPercents(
            ProvidingVolume[] providingVolumes, ReceivingVolume[] receivingVolumes)
        {
            var percents = 
                from percent in
                    from prov in
                        from p in providingVolumes
                        group p by p.Provider into pg
                        let total = pg.Sum(v => v.Volume)
                        from pp in pg
                        select new { pp, total }
                    join rec in
                        from r in receivingVolumes
                        group r by r.Account into rg
                        let total = rg.Sum(v => v.Volume)
                        from rr in rg
                        select new { rr, total }
                    on prov.pp.Account equals rec.rr.Account
                    select new Percent
                    {
                        Provider = prov.pp.Provider,
                        Receiver = rec.rr.Receiver,
                        Account  = prov.pp.Account,
                        Value    = prov.pp.Volume / prov.total * rec.rr.Volume / rec.total
                    }
                group percent by percent.Provider;

            return percents.ToDictionary(p => p.Key, p => p.ToList());
        }
Re[22]: Для увеличения лаконичности еще var использовать
От: Undying Россия  
Дата: 25.11.09 05:50
Оценка:
Здравствуйте, IT, Вы писали:

IT>В данном случае простота напрямую зависит от уровня подготовки. Не секрет, что один и тот же код для одного человека может быть простым, а для другого сложным. Это как раз тот самый случай. Вот тут
Автор: IT
Дата: 22.09.08
я давал пример одного и того же алгоритма на Linq и в императивном стиле. Разница очевидна. ФП привносит в код декларативность, а значит простоту и гибкость. Но всё это требует определённой подготовки.


Ежели сильно нужна лаконичность, то можно все переменные на var заменить, хотя читабельность это несколько ухудшит (за исключением использования var при создании Dictionary).
Re[30]: Кстати
От: samius Япония http://sams-tricks.blogspot.com
Дата: 25.11.09 07:09
Оценка: 14 (1) +1
Здравствуйте, lomeo, Вы писали:

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


VD>>Не к реляционным, а к спискам. Просто спискам. Просто таблицы в РСБУД — это тоже списки кортежей. Вот и все.

VD>>Все что может быть представлено в виде списка может быть обработано линком.

L>А LINQ работает с деревом?

L>Если да — from obj in tree select obj.name — вернёт дерево имён или просто список?
И да и нет. Ответ зависит от наличия соответствующей реализации Query expression pattern-а. В дотнете идет реализация этого паттерна для всех типов, которые реализуют IEnumerable<T>. Но ничто не мешает обеспечить собственную реализацию для ITree<T>. Тогда from obj in tree select obj.name вытащит имена из дерева объектов и вернет дерево имен.

Здесь можно увидеть примеры других реализаций query expression pattern-a.
Re[31]: Кстати
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 25.11.09 07:39
Оценка:
Здравствуйте, samius, Вы писали:

L>>Если да — from obj in tree select obj.name — вернёт дерево имён или просто список?

S>И да и нет. Ответ зависит от наличия соответствующей реализации Query expression pattern-а. В дотнете идет реализация этого паттерна для всех типов, которые реализуют IEnumerable<T>. Но ничто не мешает обеспечить собственную реализацию для ITree<T>. Тогда from obj in tree select obj.name вытащит имена из дерева объектов и вернет дерево имен.

Странно, я предполагал, что типы функций у LINQ такие:

public static M<B> SelectMany<M, A, B>(this M<A> m, Func<A, M<B>> k)


А он получается может что угодно возвращать?
Re[29]: Кстати
От: Геннадий Васильев Россия http://www.livejournal.com/users/gesha_x
Дата: 25.11.09 08:40
Оценка: +1
Здравствуйте, VladD2, Вы писали:

ГВ>>Как это вяжется с тем, что Linq, мол, предназначен для любых источников данных? Получается, что только для тех, которые сводятся к РСУБД-like.

VD>Не к реляционным, а к спискам. Просто спискам. Просто таблицы в РСБУД — это тоже списки кортежей. Вот и все.
VD>Все что может быть представлено в виде списка может быть обработано линком.

Интересная мысль, но не совсем так. Список всё же подразумевает отношение порядка "последующий-предыдущий", или хотя бы "голова-хвост". В случае с LINQ ключевая концепция другая — итератор. Однонаправленный, заметь.
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Re[30]: Кстати
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 25.11.09 08:46
Оценка: 1 (1)
Здравствуйте, Геннадий Васильев, Вы писали:

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


ГВ>>>Как это вяжется с тем, что Linq, мол, предназначен для любых источников данных? Получается, что только для тех, которые сводятся к РСУБД-like.

VD>>Не к реляционным, а к спискам. Просто спискам. Просто таблицы в РСБУД — это тоже списки кортежей. Вот и все.
VD>>Все что может быть представлено в виде списка может быть обработано линком.

ГВ>Интересная мысль, но не совсем так. Список всё же подразумевает отношение порядка "последующий-предыдущий", или хотя бы "голова-хвост". В случае с LINQ ключевая концепция другая — итератор. Однонаправленный, заметь.


Не итератор, а генератор итераторов. Он полностью изоморфен функциональному определению списка в виде голова:хвост.
Re[32]: Кстати
От: samius Япония http://sams-tricks.blogspot.com
Дата: 25.11.09 09:55
Оценка:
Здравствуйте, lomeo, Вы писали:

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


L>>>Если да — from obj in tree select obj.name — вернёт дерево имён или просто список?

S>>И да и нет. Ответ зависит от наличия соответствующей реализации Query expression pattern-а. В дотнете идет реализация этого паттерна для всех типов, которые реализуют IEnumerable<T>. Но ничто не мешает обеспечить собственную реализацию для ITree<T>. Тогда from obj in tree select obj.name вытащит имена из дерева объектов и вернет дерево имен.

L>Странно, я предполагал, что типы функций у LINQ такие:


L>
L>public static M<B> SelectMany<M, A, B>(this M<A> m, Func<A, M<B>> k)
L>


L>А он получается может что угодно возвращать?
Re[32]: Кстати
От: samius Япония http://sams-tricks.blogspot.com
Дата: 25.11.09 09:57
Оценка:
Здравствуйте, lomeo, Вы писали:


L>Странно, я предполагал, что типы функций у LINQ такие:


L>
L>public static M<B> SelectMany<M, A, B>(this M<A> m, Func<A, M<B>> k)
L>


взял из спецификации:

class C<T>
{
   public C<V> SelectMany<U,V>(Func<T,C<U>> selector,
        Func<T,U,V> resultSelector);
}

или
public C<V> SelectMany<U,V>(this C<T> source, Func<T,C<U>> selector,
        Func<T,U,V> resultSelector);


L>А он получается может что угодно возвращать?


Что угодно C<V> может делать из C<T>.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.