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

Аналоги LINQ в Scala?

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

4b9b3361

Ответ 1

Это зависит от того, что именно вы подразумеваете под "LINQ". LINQ - это много чего.

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

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

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

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

Также не является прямой частью LINQ, но в С# выражения запроса 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 is map, Aggregate is reduce (или fold), SelectMany - flatMap, Where - filter или withFilter, orderBy - sort или sortBy или sortWith, и есть zip, take и takeWhile и т.д. Таким образом, это касается как спецификации, так и реализации LINQ-to-Objects. Scala XML-библиотеки также реализуют API-интерфейсы коллекций, которые заботятся о LINQ-to-XML.

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

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

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

Ответ 2

Все расширения 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);

scala:

val total = orders
       .filter(o => o.customer == "myCustomer")
       .flatMap(o => o.orderItems)
       .foldLeft(0)((s, c) => s + c.price * c.count)

Ответ 3

Слик

- это современный запрос к базе данных и библиотека доступа для 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) }

Ответ 4

В 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