2014-11-27 20 views
8

Birisi bu F # merakını açıklayabilir mi?Arabirimlerdeki akıcı argümanlar

type IFoo = 
     abstract member Bar1: int * int -> int * int 
     abstract member Bar2: int * int -> (int * int) 
     abstract member Bar3: (int * int) -> int * int 

    type Foo() = class end 
     with 
     interface IFoo with 
      member this.Bar1 (x, y) = (x, y) 
      member this.Bar2 (x, y) = (x, y) // Same impl as Bar1 i.e. parentheses on RHS of -> in interface member definition are ignored 
      // member this.Bar3 (x, y) = (x, y) // Compile error: "This override takes a different number of arguments to the corresponding abstract member" 
      member this.Bar3 tuple = tuple // So, parentheses on LHS of -> in interface member definition *does* make a difference! 

IFoo.Bar1 ve IFoo.Bar3 tanımları arasındaki anlam farkı nedir? bir demet veya CLI yönteminin argüman listesi:

cevap

9

Burada, giriş tipi iki farklı şeyler anlatabilir. Bu dönüş türü yalnızca yorumlanması tuple olduğundan

Bu, dönüş tipine hiç fark etmez. Ancak argüman listesinde, iki argüman alan bir CLI yöntemi veya bir argüman alan bir CLI metodu arasında karar verebilirsiniz, bu bir tuple olur. İkincisi, ekstra parantez ile gösterilir.

Bu nedenle, Bar3'ü tek bir argüman ile, trolle olarak yazılan, diğerleriyle mümkün olmayan (F # 3) olarak uygulayabilirsiniz.

Bu aynı zamanda çift parantez tek parantez için bir fark yaratmak bir yerdir. Bar3 soyut değilse, member this.Bar3 ((arg1, arg2)) olarak bildirerek tuple girişini zorlayabilirsiniz.

yöntem argüman listeleri, örneğin isteğe bağlı argümanlar olarak ilave özellikleri de vardır. Yani:

type Test() = 
    member t.BarA(a, ?b) = a 
    member t.BarT((a, ?b)) = a // Error 

son satırı b şimdi tuple desen parçası, yöntemin argüman listede olmayan bir argüman olduğundan, "İsteğe Bağlı argümanlar sadece tip üyelerine izin verilir" hatası vermeye başladı.

+0

İlginç - CLI ayrıntıları F # sözdizimine sızıyor. Sanırım bu, ortak nedenlerden dolayı gerekli mi? Saf F # kodu için, iki durumu ayırt etmek için herhangi bir sebep göremiyorum. – Akash

+1

@Akash Neden olursa olsun, CLI yöntemlerinin dünyası çok paradigma dili olarak F # nin bir parçası haline gelmiştir. Aşırı yüklenme, kalıtım ve geçersiz kılma, isteğe bağlı argümanlar ve benzerleri vardır ve bu özellikler null'un olduğu gibi interop olarak ayrılmaz. Ancak, her zaman işlevsel ilk programlama ile iyi birleştirmezler. Saf fonksiyonel kodda, bu özellikler kullanılmaz, dolayısıyla işlevsel kısım CLI yöntemlerine iyi eşleşir - sorunuzda gösterilen nadiren gariplik dışında. – Vandroiy