PureScript"内部"量化类型

时间:2017-03-09 16:54:49

标签: 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 个答案:

答案 0 :(得分:1)

类型Array a中包含哪些值?

好吧,如果您知道a是什么,或者a,那么您可以提供具体的例子。如果知道aInt,那么[1, 2, 3]就是一个很好的答案。如果aMonoid个实例,则[mempty]有效。但是,如果您对a一无所知,那么您可以自信地回答的唯一答案是[]

类型forall a. Array a中包含哪些值?

对于Array a的任何选择,任何居住在该类型中的值都必须居住a。由于我们对a一无所知,答案是#34;只有[]"再次。因此,在这种情况下,forall将我们限制为只有一种类型的可能实现。

现在forall a. Array a类似于任何其他类型,因此它可以显示为函数的参数类型。作为此类函数的调用者,您只能提供一个可能的值。作为该函数的实现者,您可以选择将参数与任何类型a一起使用(因为它必须适用于您选择的任何类型)。

runST也是如此。 runST的实施者可以选择使用任何h来调用您的操作,因此它(从概念上)会生成一个新的内存区域供您使用。作为调用者,您必须处理所给予的任何内存区域,而不了解它。这意味着您只能抽象地使用提供的操作(newSTRefwriteSTRef等),并且您创建的任何引用都不能离开runST块的范围(类型变量{毕竟,{1}}不存在于该范围之外,这允许h安全地返回纯结果。

因此,runST是一个有用的工具,用于限制可以作为函数参数提供的值。