Аналоги LINQ в Скале? - PullRequest
       5

Аналоги LINQ в Скале?

46 голосов
/ 24 сентября 2010

Существуют ли какие-либо вменяемые аналоги LINQ (.NET) для Scala?

Ответы [ 4 ]

55 голосов
/ 24 сентября 2010

Это зависит от того, что именно вы подразумеваете под «LINQ». LINQ это много вещей.

Самый очевидный ответ: просто используйте порт .NET Scala. Это дает вам полный собственный доступ ко всему в .NET, который, очевидно, включает в себя LINQ.

К сожалению, .NET-порт Scala был удален пару лет назад. К счастью, его снова взяли пару месяцев назад при официальном финансировании напрямую от Microsoft. Вы можете ожидать релиз в какое-то время в 2011/2012 гг.

В любом случае, что такое LINQ?

Пара функций, добавленных в .NET и, в частности, C # и VB.NET для LINQ. Технически они не являются частью LINQ, но являются необходимыми предварительными условиями: вывод типов, анонимные (структурные) типы, лямбда-выражения, типы функций (Func<T...> и Action<T...>) и деревья выражений. Все это было в Скале в течение длительного времени, большинство из них были там навсегда.

Также не напрямую в LINQ, но в C # выражения запросов LINQ могут использоваться для генерации XML, чтобы эмулировать литералы XML VB.NET. Scala имеет XML-литералы, такие как VB.NET.

Более конкретно, LINQ - это

  • спецификация для набора стандартных операторов запросов
  • набор реализаций для этих операторов (то есть IQueryable, LINQ-to-XML, LINQ-to-SQL, LINQ-to-Objects)
  • встроенный встроенный синтаксис для понимания запросов LINQ
  • монада

В Scala, как и почти во всех других функциональных языках (и, фактически, также почти во всех других объектно-ориентированных языках), операторы запросов просто являются частью стандартного API коллекций. В .NET они имеют немного странные имена, тогда как в Scala они имеют те же стандартные имена, что и в других языках: Select - это map, Aggregate - это reduce (или fold), SelectMany это flatMap, Where это filter или withFilter, orderBy это sort или sortBy или sortWith, и есть zip, take и takeWhile и так далее. Таким образом, это заботится как о спецификации, так и о реализации LINQ-to-Objects. XML-библиотеки Scala также реализуют API коллекций, которые заботятся о LINQ-to-XML.

API-интерфейсы SQL не встроены в Scala, но существуют сторонние API-интерфейсы, которые реализуют API коллекции.

Scala также имеет специализированный синтаксис для этих API, но в отличие от Haskell, который пытается сделать их похожими на императивные блоки C и C #, который пытается сделать их похожими на запросы SQL, Scala пытается сделать их похожими на циклы for , Они называются for понимания и являются эквивалентом понимания запросов C # и понимания монадами Хаскелла. (Они также заменяют C # foreach и генераторы (yield return)).

Но если вы действительно хотите знать, есть ли аналоги для LINQ в Scala, вам сначала нужно будет уточнить, что именно вы подразумеваете под "LINQ". (И, конечно, если вы хотите знать, являются ли они «вменяемыми», вам также придется это определить.)

38 голосов
/ 24 сентября 2010

Все расширения LINQ IEnumerable доступны в Scala. Например:

Linq:

var total = orders
       .Where(o => o.Customer == "myCustomer")
       .SelectMany(o => o.OrderItems)
       .Aggregate(0, (sum, current) => sum + current.Price * current.Count);

Скала

val total = orders
       .filter(o => o.customer == "myCustomer")
       .flatMap(o => o.orderItems)
       .foldLeft(0)((s, c) => s + c.price * c.count)
10 голосов
/ 11 января 2013

Slick

- современная библиотека запросов и доступа к базе данных для Scala.(http://slick.typesafe.com/)

@table("COFFEES") case class Coffee(
  @column("COF_NAME")  name:  String,
  @column("SUP_ID") supID: Int,
  @column("PRICE") price: Double
)
val coffees = Queryable[Coffee]


// for inserts use lifted embedding or SQL
val l = for {
  c <- coffees if c.supID == 101
  //                       ^ comparing Int to Int!
} yield (c.name, c.price)


backend.result( l, session )
 .foreach { case (n, p) => println(n + ": " + p) }
8 голосов
/ 24 сентября 2010

В Scala существует множество ситуаций, когда вы можете использовать монадические конструкции в качестве своего рода языка запросов.

Например, для запроса XML (в данном случае извлечение URL-адресов из ссылок в некоторых XHTML):

def findURLs(xml: NodeSeq): Seq[URL] = 
  for {
    a <- xml \\ "a"
    href <- a attribute "href"
    url <- href.text
  } yield URL(url)

Для аналога LINQ to SQL наиболее близким, вероятно, является ScalaQuery .Чтобы поднять пример прямо из документов:

val q4c = for {
  u <- Users
  o <- Orders if o.userID is u.id
} yield u.first ~ o.orderID
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...