2012-01-23 21 views
9
public static Func<V> To<T, V>(this Func<T> g, Func<T, V> h) 
{ 
    return() => h(g()); 
} 

public static Func<T> ToIdentity<T>(this T t) 
{ 
    return() => t; 
} 

Thỉnh thoảng tôi sử dụng chúng và những người khác khi trì hoãn việc đánh giá. Những cái này đã có trong thư viện .net chưa?Có sẵn trong các cấu trúc C# /. NET chức năng như thế này không? g (h()), hoặc

Edit:

Đây là một cách sử dụng ví dụ:

public static string SuffixColumn(this string v, string suffix, int columns) 
{ 
    return 
    v.ToIdentity() 
     .ToScrubbedHtml() 
     .ToFormat(() => "{0} " + suffix.ToLower().PadLeft(columns, ' ')) 
     .ToErrorText(v, suffix, columns)(); 
} 

ToErrorText kiểm tra 'v' là hợp pháp (mã không lỗi, không null, vv), nếu tốt nó chạy chuỗi trong Func, nếu xấu nó tạo ra kết quả văn bản không an toàn. Nếu v, hậu tố, hoặc cột không tốt thì ToFormat sẽ không bao giờ được gọi. (Do đó việc sử dụng chậm/không được đánh giá).

ToFormat gần như là thành phần của Func và string.Format được cung cấp. ToIdentity được sử dụng để nâng v thành Func và sau đó mọi thứ trong chuỗi dựa trên một số Func của T.

+1

làm thế nào để bạn trì hoãn việc đánh giá sử dụng mã được cung cấp? – Tigran

+3

Câu trả lời ngắn gọn là không. Tôi tò mò mặc dù. Đây là những combinators khá lạ thường ở chỗ chúng trả về các phương thức không có đối số. Bạn đang sử dụng chúng để làm gì? Ngoài ra, sau này là xấu tên; một hàm nhận dạng có thuộc tính rằng đầu vào của nó bằng với đầu ra của nó, nhưng hàm trả về ở đây không có đầu vào. –

+0

Cảm ơn phản hồi - Tôi không thực sự chắc chắn điều gì khác để gọi ToIdentity. Và To() có lẽ nên được gọi là Soạn thư. Nhưng mỗi kết quả trong một chức năng mà không có bất kỳ đối số, do đó, không chính xác cùng một điều. – lucidquiet

Trả lời

34

Hãy để tôi xem liệu tôi hiểu: bạn đang sử dụng lambdas để nắm bắt các giá trị trong một đối tượng "wrapper" - một Func<T> - và sau đó xây dựng một quy trình làm việc của các chức năng một cách lười biếng đánh giá lại xung quanh đối tượng bọc, đúng không?

enter image description here

Mặc dù việc xây dựng nó ra khỏi chức năng công trình, cá nhân tôi sẽ được nghiêng để xây dựng đơn nguyên ra khỏi một số loại tùy chỉnh; có vẻ như quá dễ dàng để bập bẹ các chức năng tác động lên loại đơn sắc hoặc loại "cơ bản" của nó với trường hợp của chính đơn nguyên đó là. Về cơ bản, bạn đang xây dựng các chức năng sử dụng monad bằng các chức năng; Tôi muốn có khuynh hướng đơn giản hơn để tạo ra một lớp học hoặc một giao diện với một cái tên phản ánh mục đích mà bạn đang đặt bản sắc đơn sắc.

Bạn cũng có thể xem xét đổi tên phương thức của mình. "To" của bạn thường được gọi là "Bind" và "ToIdentity" của bạn theo truyền thống được gọi là "Đơn vị".

Đó là, một mô hình đơn nguyên cho một loại đơn nguyên M<T> thường có các phương pháp:

public static M<V> Bind<U, V>(this M<U> m, Func<U, M<V>> k) 

public static M<T> Unit<T>(this T value) 

Các ràng buộc cho phép bạn thực hiện các thành phần của chức năng trên monads đó là tương tự như các hàm tạo thành các loại "cơ bản" của các đơn vị.

Đối với một giới thiệu nhẹ nhàng đến kỳ diệu của monads trong C#, xem bài viết tuyệt vời đồng nghiệp xưa của tôi Wes Dyer về đề tài này:

http://blogs.msdn.com/b/wesdyer/archive/2008/01/11/the-marvels-of-monads.aspx

Để trả lời câu hỏi thực tế của bạn:

Những thư viện này đã có trong thư viện .net chưa?

Những chức năng chính xác này không có trong khung. Nhưng chức năng rất giống với những chức năng tồn tại trong khung công tác. Ví dụ: SelectMany trên IEnumerable<T> tương tự như phương thức To của bạn; nó thực hiện các hoạt động liên kết monadic trên trình tự. new Nullable<int>(123) tương tự như phương pháp "ToIdentity" của bạn; nó thực hiện các hoạt động đơn vị monadic cho "có lẽ monad". Và cứ thế.

Hệ thống loại CLR không đủ phong phú để thể hiện mẫu đơn lẻ nói chung; cho rằng bạn cần một hệ thống kiểu "cao hơn", giống như của Haskell. Bạn sẽ phải tự mình xây dựng từng đơn vị cụ thể. Tuy nhiên, có vẻ như bạn đang trên con đường của bạn.

Vài suy nghĩ nhiều hơn về việc sử dụng monads trong C# -like ngôn ngữ:

Monads in C# -- why Bind implementations require passed function to return a monad?

Monad in plain English? (For the OOP programmer with no FP background)

Why there is no something like IMonad<T> in upcoming .NET 4.0

Help a C# developer understand: What is a monad?

+0

Thông minh để nhận ra những điều này dưới hình thức ngụy trang. – jason

+9

lol tại clippy: D –

+0

Bây giờ có một tính năng VS thực sự cần để có được. XCode và Eclipse sẽ không bao giờ có khả năng cạnh tranh. – MgSam

2

Bạn có thể sử dụng Lazy để tải giá trị lười biếng.

Lazy<int> lazy = new Lazy<int>(() => delayEvaluatingMe()); 
int delayed = lazy.Value; 
+0

Điều này thậm chí không trả lời câu hỏi. – jason

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