避免型別註釋

我們使用型別註釋來避免歧義。型別應用程式可用於相同目的。例如

x::Num a => a
x = 5

main::IO ()
main = print x

此程式碼存在歧義錯誤。我們知道 a 有一個 Num 例項,為了列印它,我們知道它需要一個 Show 例項。如果 a 例如是 Int,這可能有效,所以要修復錯誤我們可以新增型別註釋

main = print (x::Int)

使用型別應用程式的另一種解決方案如下所示

main = print @Int x

要理解這意味著我們需要檢視 print 的型別簽名。

print::Show a => a -> IO ()

該函式採用 a 型別的一個引數,但另一種檢視它的方法是它實際上需要兩個引數。第一個是型別引數,第二個是型別是第一個引數的值。

值引數和型別引數之間的主要區別在於,當我們呼叫它們時,後者會隱式地提供給函式。誰提供給他們?型別推理演算法! TypeApplications 讓我們做的是明確地給出那些型別引數。當型別推斷無法確定正確的型別時,這尤其有用。

所以要打破上面的例子

print::Show a => a -> IO ()
print @Int::Int -> IO ()
print @Int x::IO ()