2012-06-09 83 views
3

F#允許簽名的「.NET」和「OCaml」格式。如果您習慣於使用一種風格,然後發現無法正確格式化所需簽名的情況,這可能會造成混淆。考慮以下代碼,這需要一個靈活的類型作爲函數的輸入輸出爲foo:簽名的「.NET」和「OCaml」格式化

let foo n (bar: int -> #seq<'a>) = 
    (fun() -> Vector.ofSeq (bar n)) 

let foobar n = Array.ofSeq([1..n]) 

let x = foo 10 foobar 

我無法弄清楚如何表達#seq <「一> OCaml中的格式。可能嗎?

回答

4

下編譯就好:

type A<'a>(x) = 
    member __.Get : 'a = x 
    abstract PairWith : 'b -> ('a * 'b * int) 
    default __.PairWith y = x, y, 1 

type B<'a>(x) = 
    inherit A<'a>(x) 
    override __.PairWith y = x, y, 2 

let pairAB (x : #A<'a>) y = 
    x, x.PairWith y 

type 'a X (x) = 
    member __.Get : 'a = x 
    abstract PairWith : 'b -> ('a * 'b * int) 
    default __.PairWith y = x, y, 1 

type 'a Y (x) = 
    inherit X<'a>(x) 
    override __.PairWith y = x, y, 2 

let pairXY (x : #('a X)) y = 
    x, x.PairWith y 

所以,你可以猜測(然後用F#交互確認),您正在尋找#('a seq)

+0

完美。我不確定F#團隊希望通過允許兩種簽名樣式。必須有一些優勢。我知道我不經意地混合了這些風格,這隻會讓人感到困惑。 –

+0

@Jack OCaml風格是爲了向後兼容,.Net風格是因爲F#在.Net上(因此應儘可能使用它的樣式和約定)。 –

1

我不完全確定你的意思,但我假設你想把類型變量放在類型名稱的前面,例如, 'a #seq

根據該語言規範(§5.1.5),因爲這是不可能的:

A型形式#type的是匿名類型與子類型約束,並且等價於'a when 'a :> type,其中'a是一個新鮮的類型推斷變量。

所以你可以寫你的類型,如:'a when 'a :> seq<'b>

編輯:你實際上可以使用#('a seq),但它看起來很尷尬,我懷疑它是你想要的。

編輯2:沒有看到拉蒙斯尼爾的回答:)。