2011-08-22 31 views
9

Gác lại cho dù chúng ta nên sử dụng đơn vị đo lường cho các khái niệm unitless như góc, giả sử tôi có định nghĩa degreeradian đơn vị trong F #Làm cách nào để xác định thành viên mở rộng trên đơn vị đo lường F #?

type [<Measure>] degree = 
    static member ToRadians (d:float<degree>) : float<radian> = d * (Math.PI * 1.<radian>)/180.0<degree> 
and [<Measure>] radian = 
    static member ToDegrees (r:float<radian>) : float<degree> = r * 180.0<degree>/(Math.PI * 1.<radian>) 

tôi có thể sử dụng chúng tương đối dễ dàng như

4.0<degree> |> degree.ToRadians 

Dường như các thành viên mở rộng thậm chí còn dễ dàng hơn. Vì vậy, tôi chỉ có thể nói

let d = 4.0<degree> 
let r = d.ToRadians() 

Nhưng tôi không thể xác định các thành viên mở rộng một cách rõ ràng

type float<degree> with 
    member degrees.ToRadians() = degree.ToRadians(degrees) 

... Đây được cho tôi những lỗi sau

error FS0010: Unexpected identifier in type name. Expected infix operator, quote symbol or other token. 

Có cú pháp cú pháp cho các thành viên mở rộng trên các đơn vị đo lường trong F #, hoặc là tính năng được hỗ trợ?

+0

Tôi sẽ nguy hiểm khi đoán rằng nó không được hỗ trợ. Tất cả mọi thứ tôi đã thử đã đưa ra lỗi: 'Các phép khai báo có thể chỉ có các thành viên tĩnh'. – Daniel

+1

Vấn đề là thông tin loại đo được loại bỏ sau khi biên dịch, do đó, ở thời gian chạy mọi thứ chỉ là một 'float' để gọi một phương thức thể hiện không có ý nghĩa –

+1

@jpalmer. Trong các thành viên mở rộng biên dịch được giải quyết tĩnh. –

Trả lời

5

Thành viên mở rộng F # khác với các thành viên mở rộng C# trong đó bạn không thể xác định các phần mở rộng của các kiểu chung chung được xây dựng. Ví dụ: bạn có thể xác định tiện ích mở rộng trên seq<'t>, nhưng không phải là seq<int>. Nói cách khác, các thành viên mở rộng thực sự hành động giống như các thành viên của kiểu, chứ không phải là các phương thức tĩnh. Này áp dụng cho đo lường các loại quá, vì vậy bạn không thể xác định một phần mở rộng trên float<degree>, nhưng bạn có thể xác định một phần mở rộng trên float<[<Measure>]'u>:

type float<[<Measure>]'u> with 
    member f.Squared() = f * f 

[<Measure>] 
type m 

let area = 2.0<m>.Squared() 

Tuy nhiên, tôi không thấy thế nào điều này sẽ giúp bạn trong trường hợp của bạn ..

+0

Điều đó có ý nghĩa tốt. Không có lợi ích thực sự nào từ việc xác định các phương thức mở rộng này ngoài cú pháp và có rất nhiều lựa chọn tốt khác. –

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