2012-07-28 77 views
4

我有很多不同的類型有共同的目的,但沒有其他共同點。爲了便於說明,他們很可能會成爲沿着線:F#類型系統可以這樣做嗎?

type blah<'a> = Blah of 'a 

type huha<'a> = Huha of 'a 

我經常需要重複樣板的一大塊,可以去一個函數內部的線沿線的:

let f (x:something<int>) (g:something<char> -> float) : float = 

但是,這需要以某種方式強制這兩種類型的東西是相同的。換句話說,我希望能夠調用的函數f:顯然

f (Blah 1) (fun (b:blah<float>) -> ....) 
f (Huha 1) (fun (b:huha<float>) -> ....) 

,一個簡單的解決方案是創建所有類型的函數f也可能採取的歧視工會,並讓每克(即f的第二個參數)檢查它得到任何類型的預期。但是這意味着擁有一個龐大的類型,在每次任何事情發生變化時都會導致Universe重新編譯,而且它不像在運行時檢查類型也有幫助。

那麼,有人可以看到一種做我想要的類型安全方式嗎?非常感謝。

+0

由於這是.NET,你可以使用一個界面 - 但我不知道他們是F#中多麼普遍。 – phg 2012-07-28 10:17:20

+0

接口在F#中實現,但我不確定這將如何幫助。所以我讓我所有的各種類型實現一些特定的接口。現在我只想寫一次代碼的副本需要進入每種類型。而當我想調用該代碼時,我需要動態調度來獲取正確的實例。但是實現必須具有相同的類型,因此我還需要使所有參數以一些常見方式運行。這似乎具有使用歧視工會的所有弊端,並且也會更加複雜?我錯過任何明顯的事情嗎? – user1559410 2012-07-28 10:50:11

回答

2

據我所知,你不能直接在F#中執行此操作。

但也許運營商超載將有所幫助。不過,您必須爲每種類型實施f。但也許你可以委託一個通用的實現。

運算符重載的代碼示例,確保正確的類型:

type T<'a> = 
    | T of 'a 
    static member (.+.) (l:T<int>, r:T<char> -> float) = 42.0 

type U<'a> = 
    | U of 'a 
    static member (.+.) (l:U<int>, r:U<char> -> float) = 13.1 


let ft (t:T<char>) = 42.0 

let fu (t:U<char>) = 42.0 

let t = T 42 .+. ft 
let u = U 13 .+. fu 

// does not compile: 
let wrong = T 42 .+. fu 
+0

非常感謝您的答覆 – user1559410 2012-07-30 10:01:01