Unbound总是需要在`FreshM` monad中吗?

时间:2016-03-03 00:40:57

标签: haskell scope lambda-calculus

我正在开发基于使用some existing code库的unbound的项目。

代码使用unsafeUnbind一堆,这导致我的问题。

我已尝试使用freshen,但收到以下错误:

error "fresh encountered bound name! 
Please report this as a bug."

我想知道:

  • 该库是否完全在FreshM monad中使用?或者他们的方法是在没有Fresh的情况下执行lambda应用程序?
  • 我可以为freshen提供哪些值,以避免列出的错误?
  • 如果我最终使用unsafeUnbind,在什么条件下可以安全使用?

1 个答案:

答案 0 :(得分:6)

  

该库是否完全在Fresh M monad中使用?或者他们的方法是在没有Fresh的情况下执行lambda应用程序?

在大多数情况下,您需要在FreshLFresh monad中操作。

  

我可以为freshen提供哪些值,以避免列出的错误?

所以我认为您收到错误的原因是因为您将术语传递给freshen而不是模式。在Unbound中,模式类似于名称的概括:单个Name E是由单个变量组成的模式,代表E s,但(p1, p2)[p]是模式分别由一对模式p1p2或模式列表p组成。例如,这允许您定义同时绑定两个变量的术语。其他更奇特的类型构造函数包括Embed tRebind p1 p2前者创建一个模式,在模式中嵌入一个术语,而后者类似于(p1,p2),但p1中的名称除外}范围超过p2(例如,如果p2中包含Embed个ed术语,p1将超出这些术语的范围。这非常强大,因为它可以让您像依赖类型语言一样定义Scheme的let*形式或望远镜等内容。 (详见论文)。

现在最终类型构造函数Bind p t将术语和类型组合在一起:术语Bind p t表示p中的名称绑定在Bind p t和范围内超过t。因此,data Expr = Lam (Bind Var Expr) | App Expr Expr | V Var type Var = Name Expr可以构造一个(无类型的)lambda术语。

回到freshen。您只应在模式上调用freshen,因此在Bind p t类型的内容上调用它是不正确的(我怀疑您看到的错误消息的来源) - 您应该仅在p上调用它,然后将结果排列应用于术语t,以应用freshen构造的重命名。

  

如果我最终使用`unsafeUnbind,在什么条件下使用它是安全的?

我使用它的地方是,如果我需要暂时潜入一个活页夹,并做一些我知道肯定对名称没有任何操作的操作。一个例子可能是从一个术语中收集一些源位置注释,或者用一个封闭的术语替换一些全局常量。此外,如果您可以保证已经重命名了您正在使用的术语,那么您unsafeUnbind的任何名称都将是唯一的。

希望这有帮助。

PS:我维护unbound-generics这是Unbound的克隆,但是使用GHC.Generics而不是RepLib。