Используя LINQ в F #? - PullRequest
       2

Используя LINQ в F #?

14 голосов
/ 13 июля 2011

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

Ответы [ 4 ]

19 голосов
/ 13 июля 2011

У LINQ есть два вида аспектов. Одним из них является языковая сторона, например в C # есть (контекстуальные) ключевые слова, такие как from и select и where, которые вы можете использовать для написания довольно SQL-подобного кода, который выполняет запросы через IEnumerable s и еще много чего. Это относительно тонкий синтаксический сахарный слой, который преобразуется в вызовы библиотеки 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 способами, которые идиоматичны для данного языка программирования.

11 голосов
/ 13 июля 2011

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

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

3 голосов
/ 13 июля 2011

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

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

1 голос
/ 01 июля 2017

Я согласен с ответом @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"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...