2012-05-23 55 views
10

如果我有一個隱式轉換C#類翻一番,像這樣:是否有使用F#的C#隱式運算符?

public class Parameter 
{ 
    private double _value; 
    public Parameter(double value) { _value = value } 
    public static implicit operator double(Parameter p) { return _value; } 
} 

F#不喜歡我嘗試使用它,彷彿它是一個float

let a = Parameter(4.0) 
let b = Parameter(2.0) 
let c = a * Math.Sin(b) <-- 'expected float, here Parameter' 

有任何方式來做到這一點(我猜根據this question/answer)沒有,如果不是,什麼是一個體面的解決方法?

+0

想一想:我可以添加一個'Value'屬性,並在任何地方使用它,它不是美麗的,但不那麼醜陋,我可以想到的其他任何東西... ... – Benjol

+1

可悲的是不... .../1686895/is-there-an-equivalent-to-creating-ac-sharp-implicit-operator-in -f –

回答

17

F#不執行隱式轉換,但它可以讓你定義一個明確的運營商來運行它們。見kvb's answer to a previous question

let inline (!>) (x:^a) : ^b = ((^a or ^b) : (static member op_Implicit : ^a -> ^b) x) 

這是使用statically resolved type parameters說,輸入或結果需要提供隱式轉換運營商 - 這些被編譯到名爲op_Implicit方法,所以對於一個靜態方法F#編譯器檢查有這個特殊的名字。

使用!>操作,現在可以明確地說要Parameter轉換爲float(兩次),你的代碼示例是這樣的:

let a = Parameter(4.0) 
let b = Parameter(2.0) 
let c = !> a * Math.Sin(!> b) 

我認爲不允許隱含的主要原因F#中的轉換是它會使類型推斷更加困難,編譯器很難給出好的錯誤消息。

+1

嗯,我不能確定哪個是醜的'A.Value * Math.Exp(time.Value)* Math.Sin(B.Value * time.Value)'和'!> A * Math.Exp |>時間)* Math.Sin(!> B *!> time)' – Benjol

+0

@Benjol我完全同意 - 事實上,我相信使用'!>'運算符比使用'.Value'屬性更醜陋,所以我可能會使用它。 '!>'運算符可能只在需要編寫其他通用函數時纔有用。 –