2017-03-09 77 views
1

我認爲我得到了錯誤的術語 - 讓我知道我應該用什麼來代替下面的內容。PureScript「內部」量化類型

PureScript by Example, section 8.17 Mutable State,還有的runST類型的討論:

runST :: forall a eff. (forall h. Eff (st :: ST h | eff) a) -> Eff eff a 

這裏需要注意的一點是,區域類型h的括號內量化的功能箭頭左。這意味着無論我們傳遞給runST的任何行動都必須與任何地區一起工作。

我理解的最終目標,但有人可以澄清從類型角度來看,這說法,這如何被限制如同上面?

如果可能,是否可以在較簡單的類型上顯示差異,例如:有什麼區別:

f1 :: forall i o. Array i -> Array o 
f2 :: forall o. (forall i. Array i) -> Array o 

我認爲一個簡短的例子會有所幫助。

回答

1

什麼值居住Array a

那麼,如果你知道a是什麼,或者關於a的東西,那麼你可能會給出具體的例子。如果a被稱爲Int,那麼[1, 2, 3]是一個很好的答案。如果aMonoid實例,則[mempty]有效。但是,如果您對a不瞭解,那麼您可以自信地給出的唯一答案是[]

什麼值居住forall a. Array a

居住該類型的任何值必須棲息Array a對於a的任何選擇。由於我們對a並不瞭解,所以答案是「只有[]」。所以在這種情況下,forall限制我們只能實現一種類型的可能。

現在forall a. Array a是一個類似於任何其他類型的類型,所以它可以作爲函數的參數類型出現。作爲這種功能的調用者,您只能提供一個可能的值。由於該函數的實現者,您可以選擇使用任意類型的參數a(因爲它必須適用於您選擇的任何類型)。對於runST也是如此。 runST的實現者可以選擇使用任何h來調用您的操作,因此它(概念上)會生成一個新的內存區域供您使用。作爲調用者,您必須與您提供的任何內存區域一起工作,而無需瞭解任何內容。這意味着您只能抽象地使用提供的操作(newSTRef,writeSTRef等),並且您創建的任何引用都不能離開runST塊的範圍(畢竟,該範圍之外不存在類型變量h),這允許runST安全地返回純粹的結果。

因此,forall是一個有用的工具,用於限制可作爲函數參數提供的值。