2017-02-18 97 views
1

所以我有這樣的代碼:函數返回一個函數使用的類型採取了泛型類型參數

type Zero = One = 1 | Two = 2 | Three = 3 
type Four = Five = 5 | Six = 6 | Seven = 7 

let test_1 (x : bool) : Type = 
    if x 
    then typeof<Zero> 
    else typeof<Four> 

let test_2() = 
    let ty = test_1 true 
    let e = enum<ty>(1) 
    ... 

但是在最後一行,我得到一個錯誤:Type ty not defined.

有什麼建議?

編輯:

或者,也許是這樣的:

let test_3 (x : bool) (i : int) : obj = 
    if x 
    then enum<Zero>(i) :> obj 
    else enum<Four>(i) :> obj 

我想會有一些方法來恢復類型安全?

也許這樣?

let test_4 (x : bool) (i : int) : obj * Type = 
    if x 
    then enum<Zero>(i) :> obj, typeof<Zero> 
    else enum<Four>(i) :> obj, typeof<Four> 

然後用它作爲這樣:

let test_5() = 
    let v,t = test_4 true 1 
    let o = v :?> t 
    ... 

這抱怨與T中的最後一行沒有定義。

基本上我想要做的就是能夠返回這些不同的枚舉而不訴諸包裝零和四個DU。

+3

類型參數必須是靜態已知的,它們不能是動態計算的結果。 – kvb

+4

在運行時存在'Type'實例; 'enum'需要一個編譯時參數。 – ildjarn

回答

2

你不能這樣做,「類型安全」意味着你(編譯器)知道靜態類型(不執行代碼)。通過鑄造到obj你會失去這種知識。添加運行時間類型(typeof)沒有幫助。即使你可以使用返回的元組的第二個值,那麼這會有什麼幫助?你的程序代碼將被硬編碼,無論你的價值如何。

如果在編譯時不知道這個值(例如從控制檯讀取),那麼你會假設什麼類型? t應該在以下綁定中?

let o : t = test someBool someInt 

它可以是ZeroFour,即Zero | Four,就是type Either = Zero | Four,即

type EitherEnum = 
| Z of Zero 
| F of Four 

...可識別聯合,因爲你想通了。

Basically what I'm trying to do is to be able to return these different enums without resorting to wrapping Zero and Four into a DU.

你想出如何做到這一點已經:投給obj和鬆散型的安全性。你不能兩面都有。

你在找什麼是dependent types,例如, F*規定。