2017-03-09 69 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是一个有用的工具,用于限制可作为函数参数提供的值。