【问题标题】:PureScript "inner" quantified typePureScript“内部”量化类型
【发布时间】:2017-03-11 01:47:07
【问题描述】:

我认为我在图块中的术语有误 - 让我知道我应该在下面使用什么来代替。

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 的任何操作都必须适用于任何区域 h。

我了解最终目标,但有人可以从类型的角度澄清这一说法,以及如何按照上述方式进行限制吗?

如果可能,是否可以在更简单的类型上显示差异,例如有什么区别:

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

我认为一个简短的例子会有所帮助。

【问题讨论】:

    标签: purescript


    【解决方案1】:

    Array a 类型包含哪些值?

    好吧,如果你知道a 是什么,或者关于a 的东西,那么你也许可以举出具体的例子。如果已知aInt,那么[1, 2, 3] 是一个很好的答案。如果a 有一个Monoid 实例,那么[mempty] 可以工作。但是,如果您对a 一无所知,那么您可以自信地给出的唯一答案是[]

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

    对于a 的任何选择,驻留在该类型中的任何值都必须驻留在Array a 中。由于我们对a 一无所知,所以答案又是“仅[]”。因此,forall 在这种情况下将我们限制为只有一个可能的类型实现。

    现在forall a. Array a 是一个和其他类型一样的类型,所以它可以作为函数的参数类型出现。作为此类函数的调用者,您只能提供一个可能的值。作为该函数的实现者,您可以选择使用带有 any 类型 a 的参数(因为它必须适用于您选择的任何类型)。

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

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

    【讨论】:

      猜你喜欢
      • 2014-12-11
      • 1970-01-01
      • 1970-01-01
      • 2015-07-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多