2011-04-21 55 views
0

是否有可能以某種方式使用管道傳遞帶有元組參數的方法的最後一個參數?F# - 帶有tupled參數的管道

一個例子:

// Member to call 

static member Property (expr:Expr<'a -> string>, cfg:EntityInfo<'a>) = cfg.Property expr 

// My curry function 

let curry f x y = f (x,y) 

// My EntityInfo<FileUpload> 

let entityInfo = EF.Entity<FileUpload> modelBuilder 

我希望能夠調用它像:

entityInfo |> curry EF.Property <@ fun z -> z.Path @> 

,而不是

EF.Property(<@ fun z -> z.Path @>, entityInfo) 
+0

你有什麼看起來很好看,它不起作用?什麼是錯誤? – Brian 2011-04-21 18:42:49

+0

@Brian,「方法'屬性'的唯一重載無法根據此程序點之前的類型信息確定。可用的重載如下(或在錯誤列表窗口中),可能需要類型註釋。 – ebb 2011-04-21 18:44:46

+0

啊,是的,超載,類型推斷的bugaboo。我不認爲有一種方法可以使這種語法適用於重載方法。 – Brian 2011-04-21 19:15:27

回答

2

我認爲,這是你的問題的一個簡化版本(雖然你不包括太多的代碼,以確保):

type T() = class end 

type S = 
    static member Method(_:int, T) = 'c' 
    static member Method(_:string, T) = false 

let curry f x y = f(x,y) 

// won't work 
T() |> curry S.Method 1 

布賴恩提到,超載不能很好地與類型玩推理。特別是,由於F#的類型推斷從左到右工作,編譯器在嘗試執行S.Method的成員查找時不使用1int的事實,這意味着它無法識別正確的過載。正如我所看到的,您有幾種選擇:

  1. 使用不同的方法名稱。是否有理由必須使用Property來指代多個不同的操作?對於每個超載使用StringProperty,IntProperty等等會更糟嗎?一般來說,重載會使編譯器的生活變得更加困難(通常也是人類維護者)。順便說一下,我不喜歡這種方法Property,無論如何...
  2. 使用curry顯式類型參數,並指定它們。例如。

    let curry<'a,'b,'c> f (x:'a) (y:'b) : 'c = f(x,y) 
    entityInfo |> curry<Expr<_ -> string>,_,_> EF.Property <@ fun z -> z.Path @> 
    
  3. 明確指示的EF.Property類型:

    entityInfo |> curry (EF.Property: Expr<_ -> string> * _ -> _) <@ fun z -> z.Path @> 
    

當然,這最後兩個選項都不是很簡潔的,所以他們可以擊敗使用流水線風格的目的。

+0

我的第一個想法是給他們的名字像'StringProperty'和' IntProperty',但我認爲這是不好的做法,因爲大多數人似乎更喜歡重載,但它不是? - 就像你說的那樣,你給出的最後兩個選項不是我所謂的ehmm ...整潔; p – ebb 2011-04-21 19:47:29

+0

@ebb - 它取決於...當可以用一個參數子集調用方法時,人們通常使用重載而不是完整列表 - 使用C#3或更低版本時,這是有道理的,但現在使用可選參數可能會更好。當一個方法可以採用兩種完全不同的類型時使用重載是不太常見的,我幾乎總是試圖避免使用更多的描述性名稱。在使用F#時尤其如此,因爲正如你所看到的,過載可能會對類型推斷造成嚴重破壞。 – kvb 2011-04-21 20:10:12

0

這是因爲它是計算實體的信息作爲EF.Propery方法的成員而不是咖喱方法,您應該使用

entityInfo |> curry (EF.Property) (<@ fun z -> z.Path @>) 
+0

拋出一個異常:「該成員或對象構造函數'屬性'採取2個參數不能從這個代碼位置訪問。方法'屬性'的所有可訪問版本都帶有2個參數。 – ebb 2011-04-21 18:40:13

+0

啊是對不起,修正了代碼:) – 2011-04-21 18:41:56

+0

hmm ..現在拋出:「方法'屬性'的唯一重載無法根據此程序點之前的類型信息確定。可用的重載如下所示(或在錯誤列表窗口)。可能需要類型註釋「 - 但重載應該是正確的。 – ebb 2011-04-21 18:46:37