Подтвердить что ты не робот

Использование LINQ в F #?

Учитывая, что базовый синтаксис и семантика языка, такого как F #, уже разработаны для обеспечения того, что LINQ предоставляет С#/VB в качестве добавочного, почему я должен использовать LINQ при программировании в F #? Что я получу, и что я могу потерять?

4b9b3361

Ответ 1

LINQ, с точки зрения языка (особенность С# из... синтаксиса) в основном не нужна, поскольку F # может представлять собой преобразования данных, подобные LINQ, очень лаконично уже. Я подозреваю, что большая часть оставшейся цели сахара С# заключается в реорганизации кода, поэтому С# может вводить запросы LINQ, не заставляя пользователя предоставлять аннотации типов или выполнять eta-расширение вручную. Это тоже не нужно в F #.

Что касается использования пространства имен System.Linq в F #, я не рекомендую его. Вывод типа F # становится лишним глупостью вокруг доступа к члену. Я подозреваю, что использование System.Linq потребует более явных аннотаций типа, чем использование соответствующей библиотеки F #. Даже в тех случаях, когда вывод типа преуспевает, неподтвержденный API CLR-стиля обычно чувствует себя тяжелым и неуместным в F # по сравнению с родными библиотеками.

Ответ 2

В LINQ существует два аспекта. Одна из них - это языковая сторона, например. в С# есть (контекстные) ключевые слова, такие как from и select и where, которые вы можете использовать для написания довольно-SQL-кода, который выполняет запросы по IEnumerable и еще что-то. Это относительно тонкий слой синтаксического сахара, который преобразуется в вызовы библиотеки LINQ к select и SelectMany и where и еще что-то.

Тогда существует аспект IQueryable, который позволяет повторить этот же код как IQueryable, который во многом похож на механизм цитаты, поскольку он напоминает синтаксическое дерево, которое построило запрос. И это важно, потому что тогда разные провайдеры могут подключать поведение, чтобы "скомпилировать" код по-своему, например. поставщик SQL может получить представление "всего запроса" и составить запрос с хорошим планом запросов, который будет выполняться на сервере (в отличие от наивного подхода к обработке базы данных SQL как строки IEnumerable строк и просто загрузки всех строк в памяти и фильтрации их в .NET внутри вашего клиентского приложения, которое плохо срабатывало или просто падало на большие данные).

Первый аспект - это просто синтаксический сахар и еще много чего. F # 2.0 (версия F # в VS2010) не имеет встроенной поддержки LINQ, но PowerPack имеет мост LINQ, так что вы можете использовать F # цитаты нормальных комбинаторов F # Seq как способ выражения запросов LINQ.

Второй аспект - это более существенный бит в плане общей технологии. LINQ представляет собой запрос на повторное создание запросов, чтобы программисты могли декларативно указывать намерение, а затем различные поставщики могли подключаться к системе и переводить это намерение в эффективный план выполнения для соответствующего резервного хранилища данных..NET 3.5. Типы деревьев выражений являются "интерфейсом" к этому существенному аспекту LINQ, и поэтому любой заданный язык программирования просто нуждается в некотором роде для программистов для написания выражений, которые будут генерировать эти деревья выражений.

Итак, я не чувствую, что исходный вопрос имеет смысл. Основная причина использования LINQ заключается в том, что вы хотите запросить базу данных SQL (или фид OData или...) таким образом, чтобы запрос выполнялся эффективно на сервере (или не требует использования миллиона повторяющихся HTTP-запросов, или...), и вы хотите сделать это таким образом, чтобы не требовать многого узнать о деталях этих технологий (у различных LINQ-серверов есть все индивидуальные умственные способности). Синтаксис в основном является просто синтаксисом, и на разных языках могут быть разные сахара (или механизмы сахарирования) для запросов LINQ с помощью способов, которые являются идиоматическими для данного языка программирования.

Ответ 3

Вы правы, что для коллекций в памяти F # обеспечивает большую часть поведения, обнаруженного в LINQ, через различные модули сбора, Seq, List и тому подобное. Я считаю, что отличительной особенностью LINQ является возможность подключения поставщиков запросов. В то время как F # предлагает ограниченную поддержку метапрограммирования через цитаты, нет тривиального способа, который я знаю, чтобы перевести их в нечто значимое для несохраненных резервных хранилищ (PowerPack предлагает некоторую поддержку для этого в F #).

Чтобы ответить на ваш вопрос, если вы намерены перевести запросы, а не выполнять их в коллекциях в памяти, LINQ - ваш лучший вариант. В противном случае, придерживайтесь модулей сбора F #. Используя LINQ, если этого достаточно, вы жертвуете приложением частичной функции, цепочки функций (piping), и вы напишете неидиоматический код (могут быть и другие ошибки).

Ответ 4

Я согласен с ответом @blucz, это не рекомендуется, но если вы действительно этого хотите, это выглядит так:

Импорт System и System.Linq

open System
open System.Linq

Оберните несколько методов расширения LINQ

let select  f xs = Enumerable.Select(xs, new Func<_,_>(f))
let where   f xs = Enumerable.Where(xs, new Func<_,_>(f))
let orderBy f xs = Enumerable.OrderBy(xs, new Func<_,_>(f))

И используйте его

[1..100] 
|> where (fun x -> x > 2) 
|> select (fun x -> x * 2) 
|> printfn "%A"