2011-02-24 141 views
2

我是一種新的F#所以也許我的問題是愚蠢的。我在F#中編寫了一個使用泛型類型的程序。編譯器確定的類型不是我想要的方式,因爲我在最深的函數調用中有一個錯誤,我已經將類型實例化爲錯誤的類型。這顯然導致了其他地方的類型不匹配,因爲我曾經使用過這種類型。我不得不提到找到問題的根源,我試圖明確強制執行更高級別的函數,以使用我希望用於泛型類型的類型。然而,類型不匹配顯示在那些高級函數中,而不是低級函數是類型被實例化的。我認爲這不是確定類型的非常方​​便的方式,因爲通常程序員更容易確定更高級別函數的類型,並且如果類型已確定,則此顯式類型分配應導致較低級別函數中的類型錯誤。根據我的經驗,似乎編譯器的自動類型確定會覆蓋顯式類型聲明。我在這裏理解錯誤嗎?F#類型推斷

類似下面的代碼:

type test<'a,'b>={Func:'a->'b; Arg:'a} 

let C(a)= 
    a.Func(2)|>ignore 

let B(a)= 
    C(a) 

let A(a:test<int64,int64>)= 
    B(a) //<-----------------------the type mismatch is detected here 

在這樣高水平的函數調用已經檢測到的錯誤會使得它很難找到問題的根源,因爲現在不僅我得找有關的蟲子變量的值,還有類型確定的錯誤。

+3

「編譯器的自動類型確定重寫顯式類型聲明」 - >否,它不... – 2011-02-24 02:08:19

+0

你可以發佈你的代碼嗎?否則很難給你的具體問題提供建議...... – 2011-02-24 02:08:55

+0

@Mauricio Scheffer:現在我已經添加了代碼示例。謝謝:) – amirmonshi 2011-02-24 02:26:27

回答

2

F#的類型推斷是(相當)嚴格的從上到下,從左到右。看到這裏的討論:Why is F#'s type inference so fickle?

您可以通過重新安排這樣的代碼(只是爲了演示)檢查:

type test<'a,'b>={Func:'a->'b; Arg:'a} 

let rec B(a)= 
    C(a) 

and A(a:test<int64,int64>)= 
    B(a) 

and C(a)= 
    a.Func(2)|>ignore // type mismatch now here 

便利水平主要取決於具體的代碼,以我的經驗。但我不得不承認,我也有時會因類型不匹配錯誤消息而感到驚訝。這需要一段時間才能習慣。

+0

令人驚歎!謝謝,我不知道它是這樣的。我相信如果我牢記這一點,它會爲我節省很多。我沒有看到在F#中引入更好類型的推理時存在什麼障礙,它將優先考慮更明確的語義而不是聲明的順序。也許這是個人的事情,但我認爲,例如在上面的例子中,測試應該是絕對的決定因素,而不是聲明的順序。除此之外,聲明必須同時考慮類型和值實例化!這可能是非常嚴格的! – amirmonshi 2011-02-24 03:19:44