2009-09-13 68 views
10

Tôi đang tìm kiếm LINQ và ngôn ngữ truy vấn xuất hiện (ít nhất là trên bề mặt) không gì khác ngoài việc triển khai bản đồ và/hoặc hiểu danh sách như được tìm thấy trong Haskell và các ngôn ngữ FP khác (đặc biệt là khái quát 'bản đồ' và 'for' trong Scala). Điều này có đúng không? Có nhiều cú pháp hơn thế này không? Từ giai điệu khó thở của cuốn sách tôi đang đọc ("Essential LINQ") nó có vẻ như có một cái gì đó mới hoặc sáng tạo ở đây.Có bao nhiêu LINQ?

Có toàn bộ back-end, đường ống, biểu thức thứ tự đầu tiên và các loại vv để triển khai LINQ nhưng câu hỏi của tôi là về chính ngôn ngữ truy vấn.

Cheers

Joe

Trả lời

25

Nói theo chức năng, LINQ không là gì ngoài việc đơn giản hóa cú pháp thể hiện các đơn nguyên. LINQ to Objects (List-comprehensions - thậm chí điều này đã vô cùng hữu ích), mà bạn đã nói đến, chỉ là một ứng dụng có thể này (tương tự như List-Monad trong Haskell).

Nếu bạn viết

from x in expr1 
from y in expr2 
select x + y 

nó không có gì nhưng

do 
    x <- expr1 
    y <- expr2 
    return $ x + y 

trong Haskell.

Điều cụ thể được thực hiện tùy thuộc vào người dùng được xác định Nhà cung cấp LINQ (Extension-Methods) trong đó Linq.Enumerable chỉ là một triển khai liên quan đến IEnumerable s.

Bằng cách cung cấp một, bạn có thể tạo LINQ ngữ nghĩa hoàn toàn mới cho các loại của mình.

Ví dụ: Đưa ra loại Option cho các tính toán có thể thất bại (giá trị nullable), người ta có thể xác định nhà cung cấp LINQ để truy vấn trên chúng.

public static class MaybeExtensions 
{ 
public static Option<T> ToMaybe<T>(this T value) 
{ 
    return Option<T>.Some(value); 
} 

public static Option<U> SelectMany<T, U>(
    this Option<T> m, 
    Func<T, Option<U>> k) 
{ 
    return !m.IsNone ? Option<U>.None : k(m.Value); 
} 

public static Option<V> SelectMany<T, U, V>(
    this Option<T> m, 
    Func<T, Option<U>> k, 
    Func<T, U, V> s) 
{ 
    return m.SelectMany(x => k(x).SelectMany(y => s(x, y).ToMaybe())); 
} 
} 

này bây giờ sẽ cho phép chúng ta viết mã như:

var sum = from x in ReadNumber("x") 
      from y in ReadNumber("y") 
      select x + y; 

Việc tính toán sẽ chỉ trả lại một giá trị nếu tất cả các tính toán thành công và nếu không sẽ thất bại ở lần đầu tiên thất bại trong một.

Kết hợp với cây biểu thức, LINQ có thể cực kỳ mạnh mẽ và cho phép bạn thể hiện -

  1. Cơ sở dữ liệu truy cập
  2. Asynchronous programm dòng
  3. lẽ-Monads
  4. Danh sách comprehensions
  5. Recursive trình phân tích cú pháp gốc
  6. Continuations
  7. Mini-ngôn ngữ
  8. tính toán song song (PLINQ)

Một số liên kết:

Kết hợp với bộ phối hợp điểm cố định, LINQ cung cấp đầy đủ chức năng nhỏ ngôn ngữ (Linq raytracer).

Lưu ý rằng Scala và F # Cả hai đều có những khái niệm tương tự trong cho-comprehensions và các biểu thức tính toán cả hai là trừu tượng monadic:

Scala:

for (x <- expr1 
    y <- expr2) yield x + y 

F #:

monad { 
    let! x = expr1 
    let! y = expr2 
    return x + y 
} 
+0

Cảm ơn bạn đã thông tin. Tôi sẽ nhìn vào những người dẫn đầu. – Joe

+0

Thực sự, tóm tắt thực sự tốt với một ví dụ tốt đẹp, dễ nắm bắt. +1 –

+0

Tiếp tục liên kết raytracer, đây là cùng một raytracer được triển khai hoàn toàn trong một câu lệnh LINQ: http://tirania.org/blog/archive/2007/Nov-16.html – JulianR

4

Bên cạnh đọc một cuốn sách về nó, bạn đã sử dụng LINQ? Tôi thấy nó là một công cụ tiết kiệm thời gian rất lớn trong công việc lập trình hàng ngày của tôi. Đối với tôi, đó là bước trừu tượng tiếp theo, có thể được sử dụng để kết hợp các nguồn dữ liệu khác nhau như XML hoặc SQL và làm việc với chúng trong cùng một "ngôn ngữ".

Hơn nữa, tôi khuyên bạn nên interview with Anders Hejlsberg về lập trình chức năng và LINQ.

+0

Cảm ơn bạn đã trả lời và liên kết, tôi sẽ đọc nó. Có, tôi đã sử dụng nó một chút (và tôi thấy nó rất hữu ích thực sự), nhưng tôi sử dụng trong cùng một cách mà tôi đã được sử dụng bản đồ và cho trong Scala. Tôi hỏi câu hỏi này vì những điểm tương đồng và tự hỏi họ đã đi sâu đến thế nào. – Joe

5

Hơi thở có lẽ là dành cho tất cả những thứ "rõ ràng", một số trong số đó (giống như cây biểu hiện) thực sự tuyệt vời. Ngôn ngữ chỉ là phương tiện tiếp cận; bạn có hào hứng với từ khóa throw hay vượt quá chức năng mà nó hiển thị không?

+0

Tôi không có nghĩa là "rõ ràng" công cụ "là hiển nhiên, chỉ đơn giản là nó đã được thừa nhận nhưng không phải là trọng tâm của câu hỏi của tôi! Có lẽ tôi đã nói nó hơi kém. – Joe

+0

Những người khác vui lòng đọc nhận xét của Ben M bằng cách chỉnh sửa câu hỏi của tôi. – Joe

2

LINQ là cảm hứng bởi HaskellDB, như Erik Meijer đã được nêu rõ, ví dụ trong Confessions of a Used Programming Language Salesman (Getting the Masses Hooked on Haskell), vì vậy nó không phải là một khái niệm mới. Sử dụng cùng một ngôn ngữ để truy vấn các nguồn khác nhau là ở một mức độ sáng tạo, mặc dù thực tế là mô hình lồng ghép quan hệ bao gồm XML, các đối tượng và các cơ sở dữ liệu quan hệ đã được các nhà nghiên cứu đưa ra trước đây. Đối với tôi, điều cực kỳ thú vị là nó đã được nhúng vào một ngôn ngữ phổ biến, có mục đích chung và chủ yếu hướng đối tượng, vốn chưa được thực hiện trước đây.

Scala IMHO có khả năng kết hợp thứ gì đó tương tự. Cho đến nay, đối với Scala, chúng tôi có Stefan Zeiger 's ScalaQuery và , theo bước chân LINQ.

+0

Cảm ơn bạn đã liên kết, chúng trông rất hấp dẫn. – Joe

3

Cốt lõi của LINQ, cú pháp truy vấn, không thực sự lớn trong phạm vi.Nó chỉ đơn giản là một số rất đen dịch, với các phương pháp và lambdas - vì vậy

var qry = from x in src 
      where x.Foo == "foo" 
      select x.Bar; 

nghĩa đen:

var qry = src.Where(x => x.Foo == "foo").Select(x => x.Bar); 

nó không biết gì về phương pháp khuyến nông (mặc dù họ là phổ biến nhất (nhưng không thực hiện chỉ)) và không có gì về số Expression v.v. Số lượng từ khóa (và do đó số lượng triển khai phương thức bắt buộc) không lớn. Jon khi đã cố gắng triển khai tất cả chúng trong 1 giờ (trong bản trình bày trực tiếp). Ông đã không làm quá nặng ;-p


Có lẽ một phần ấn tượng hơn của LINQ là biểu hiện cây hỗ trợ mà đã được yêu cầu để cho phép LINQ to được dùng để chống lại cơ sở dữ liệu - tức là biểu thức lambda có thể được được biên soạn hoặc cho một đại biểu hoặc vào một mô hình đối tượng đại diện cho mã được viết. Điều thú vị là, ý tưởng tương tự này chiếu qua cách thức mà độ phân giải DLR hoạt động trong 4.0.

+0

Một quan điểm rất hữu ích. Cảm ơn bạn đã làm rõ. – Joe

Các vấn đề liên quan