PureScript "inner" 量化类型
PureScript "inner" quantified type
我假设我在图块中的术语有误 - 让我知道我应该在下面使用什么来代替。
在PureScript by Example, section 8.17 Mutable State中有讨论runST
的类型:
runST :: forall a eff. (forall h. Eff (st :: ST h | eff) a) -> Eff eff a
The thing to notice here is that the region type h is quantified inside the parentheses on the left of the function arrow. That means that whatever action we pass to runST has to work with any region h whatsoever.
我理解最终目标,但是有人可以从类型的角度阐明这个陈述,以及如何按照上述限制吗?
如果可能,是否可以在更简单的类型上显示差异,例如有什么区别:
f1 :: forall i o. Array i -> Array o
f2 :: forall o. (forall i. Array i) -> Array o
我认为一个简短的例子会有所帮助。
类型 Array a
包含哪些值?
好吧,如果您知道 a
是什么,或者了解 a
,那么您也许可以举出具体的例子。如果已知 a
是 Int
,那么 [1, 2, 3]
是一个很好的答案。如果 a
有一个 Monoid
实例,那么 [mempty]
有效。但是,如果您对 a
一无所知,那么您唯一可以自信地给出的答案是 []
.
类型 forall a. Array a
包含哪些值?
对于 a
的任何选择,任何属于该类型的值都必须属于 Array a
。由于我们对a
一无所知,答案又是"only []
"。所以在这种情况下,forall
将我们限制为只有一种可能的类型实现。
现在 forall a. Array a
是一个和其他类型一样的类型,所以它可以作为函数的参数类型出现。作为此类函数的调用者,您只能提供一个可能的值。作为该函数的 实现者 ,您可以选择使用具有 any 类型 a
的参数(因为它必须适用于任何类型你选择)。
runST
也是如此。 runST
的实现者可以选择使用它喜欢的任何 h
来调用您的操作,因此它(概念上)会生成一个新的内存区域供您使用。作为调用者,您必须使用给定的任何内存区域,而无需对此一无所知。这意味着您只能抽象地使用提供的操作(newSTRef
、writeSTRef
等),并且您创建的任何引用都不能离开 runST
块的范围(类型变量 h
不存在于该范围之外,毕竟),这允许 runST
到 return 一个安全的纯结果。
因此,forall
是一个有用的工具,用于限制可以作为函数参数提供的值。
我假设我在图块中的术语有误 - 让我知道我应该在下面使用什么来代替。
在PureScript by Example, section 8.17 Mutable State中有讨论runST
的类型:
runST :: forall a eff. (forall h. Eff (st :: ST h | eff) a) -> Eff eff a
The thing to notice here is that the region type h is quantified inside the parentheses on the left of the function arrow. That means that whatever action we pass to runST has to work with any region h whatsoever.
我理解最终目标,但是有人可以从类型的角度阐明这个陈述,以及如何按照上述限制吗?
如果可能,是否可以在更简单的类型上显示差异,例如有什么区别:
f1 :: forall i o. Array i -> Array o
f2 :: forall o. (forall i. Array i) -> Array o
我认为一个简短的例子会有所帮助。
类型 Array a
包含哪些值?
好吧,如果您知道 a
是什么,或者了解 a
,那么您也许可以举出具体的例子。如果已知 a
是 Int
,那么 [1, 2, 3]
是一个很好的答案。如果 a
有一个 Monoid
实例,那么 [mempty]
有效。但是,如果您对 a
一无所知,那么您唯一可以自信地给出的答案是 []
.
类型 forall a. Array a
包含哪些值?
对于 a
的任何选择,任何属于该类型的值都必须属于 Array a
。由于我们对a
一无所知,答案又是"only []
"。所以在这种情况下,forall
将我们限制为只有一种可能的类型实现。
现在 forall a. Array a
是一个和其他类型一样的类型,所以它可以作为函数的参数类型出现。作为此类函数的调用者,您只能提供一个可能的值。作为该函数的 实现者 ,您可以选择使用具有 any 类型 a
的参数(因为它必须适用于任何类型你选择)。
runST
也是如此。 runST
的实现者可以选择使用它喜欢的任何 h
来调用您的操作,因此它(概念上)会生成一个新的内存区域供您使用。作为调用者,您必须使用给定的任何内存区域,而无需对此一无所知。这意味着您只能抽象地使用提供的操作(newSTRef
、writeSTRef
等),并且您创建的任何引用都不能离开 runST
块的范围(类型变量 h
不存在于该范围之外,毕竟),这允许 runST
到 return 一个安全的纯结果。
因此,forall
是一个有用的工具,用于限制可以作为函数参数提供的值。