2012-08-06 35 views
15

Trong C#, tôi có thể xác định một phương pháp mở rộng cho một mảng chung của loại T như thế này:Làm thế nào để xác định một loại mở rộng cho T [] trong F #?

nhưng đối với cuộc sống của tôi, tôi không thể tìm ra cách để làm điều tương tự trong F #! Tôi đã thử type 'a array with, type array<'a> withtype 'a[] with và trình biên dịch không hài lòng với bất kỳ trình duyệt nào trong số đó.

Có ai cho tôi biết quyền làm điều này trong F # không?

Chắc chắn, tôi có thể làm điều này bằng cách làm lu mờ mô-đun Array và thêm chức năng cho điều đó một cách dễ dàng, nhưng tôi thực sự muốn biết cách làm như một phương pháp mở rộng!

+0

"cuộc sống của tôi" nghĩa là gì :)? – Omu

+0

Mở rộng 'System.Array' là suy nghĩ đầu tiên của tôi, nhưng một tham số kiểu và phép đúc sẽ là cần thiết trừ khi bạn đồng ý với' obj'. – Daniel

+1

@Chuck Norris - có nghĩa là 'Tôi không thể ... ngay cả sau khi tôi đã cố gắng hết sức' – theburningmonk

Trả lời

27

Bạn phải viết kiểu mảng sử dụng 'backtick dấu' - như thế này:

type 'a ``[]`` with 
    member x.GetOrDefault(n) = 
    if x.Length > n then x.[n] 
    else Unchecked.defaultof<'a> 

let arr = [|1; 2; 3|] 
arr.GetOrDefault(1) //2 
arr.GetOrDefault(4) //0 

Chỉnh sửa: Cú pháp type ``[]``<'a> with ... dường như cũng được cho phép. Trong nguồn F # (prim-types-prelude.fs), bạn có thể tìm thấy định nghĩa sau:

type ``[]``<'T> = (# "!0[]" #) 
+0

+1 Tìm tốt! Có phải là trong spec/docs? – Daniel

+0

@Daniel: Thử nghiệm. Tôi đã cố gắng tìm bất cứ điều gì trong spec/docs nhưng không thành công. –

+0

Xin lỗi, tôi đã chỉnh sửa câu hỏi của mình. Cảm ơn. – Daniel

10

Câu hỏi hay. Tôi không thể tìm ra cách để mở rộng 'T[] nhưng bạn có thể tận dụng thực tế là mảng thực hiện IList<_> làm:

type System.Collections.Generic.IList<'T> with 
    member x.GetOrDefault(n) = 
    if x.Count > n then x.[n] 
    else Unchecked.defaultof<'T> 

let arr = [|1; 2; 3|] 
arr.GetOrDefault(1) //2 
arr.GetOrDefault(4) //0 
+1

Tôi khá chắc chắn không có cú pháp pháp trong F # để thêm thành viên mở rộng vào các loại mảng, vì vậy đây có lẽ là giải pháp thay thế tốt nhất (Tôi không thể nghĩ ra bất kỳ hạn chế nào, ngoài thực tế là phương pháp này cũng xuất hiện trên bất kỳ loại IList nào khác). – Brian

+0

@Daniel - crap thánh, bạn nói đúng! 'T [] thực hiện IList <'T>! Tôi không ý kiến! không chắc chắn nếu điều đó có ý nghĩa với tôi mặc dù, một mảng có một khối liên tục của bộ nhớ, phải không? do đó, các hoạt động bổ sung chắc chắn sẽ phải phân bổ lại cho toàn bộ mảng mới mỗi lần, dường như với tôi như một cái gì đó bạn nên khuyến khích và khuyến khích sử dụng Danh sách (có bộ đệm bên trong nó quản lý). – theburningmonk

+3

'Thành viên thay đổi' IList <_> ',' Add'/'Remove', v.v. ném 'NotSupportedException'. Thử: '([| 1 |]:> System.Collections.Generic.IList <_>) .Thêm (2)' – Daniel

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