如何从类型重构Haskell表达式

时间:2013-09-08 20:48:38

标签: haskell types logic type-inference

我正在编写一个程序,对于给定类型签名,重构此类型的Haskell表达式,例如:对于a -> b -> a,它返回\x -> \_ -> x。我已经读过这个问题背后的理论,我知道有这个霍华德 - 库里的同构。我想我的程序解析输入并将其表示为术语。然后我会触发SLD分辨率,告诉我是否可以构造给定类型的术语(例如,对于Pierce来说,这是不可能的)。我还不知道如何在此分辨率期间实际创建Haskell表达式。我已经看过djinn的代码,但它有点复杂,我想掌握一些关于它是如何工作的一般概念。

1 个答案:

答案 0 :(得分:1)

如果你使用Curry-Howard将Haskell的一个子集连接到一些直觉逻辑,那么从证明术语中提取Haskell程序应该非常容易。本质上,证明术语应该已经具有与Haskell程序完全相同的结构,但只使用不同的构造函数名称。我认为如果你在适当的时候翻译你头脑中的构造函数名称,你甚至可以使用相同的代数数据类型来证明术语和Haskell术语。例如:

type Name = String

data Type                  -- aka. Formula
  = Function Type Type     -- aka. Implication
  | TypeVar Name           -- aka. PropositionalVar

data Term                  -- aka. Proof
  = Lambda Name Type Term  -- aka. ImplicationIntroduction
  | Apply Term Term        -- aka. ImplicationElimination
  | TermVar Name           -- aka. Start / Identity / Axiom / Copy

你必须在范围内使用变量的上下文(也就是你可以假设的假设)。

type TypingContext = Map Name Type -- aka. Hypotheses

鉴于这样的类型,你“只需”编写一个函数:

termOf :: Type -> TypingContext -> Maybe Term

但也许作为第一步,最好首先编写反函数,作为练习:

typeOf :: Term -> TypingContext -> Maybe Type

这两个函数的基本结构应该是相似的:模式匹配你所拥有的东西,决定哪些输入规则(又称。证明规则)是适用的,递归调用自己构造一个部分结果,通过包装完成部分结果在与输入规则(aka。证明规则)对应的构造函数中。不同之处在于typeOf可以遍历整个术语并将所有内容都计算出来,而termOf可能需要猜测并回溯猜测猜测是否有效。可能,您实际上想要termOf的列表monad。

首先撰写typeOf的好处是:

  1. 它应该更容易,因为术语往往包含的信息多于类型,因此termOf可以使用额外的信息,typeOf需要创建额外的信息。
  2. 有更多可用的帮助,因为许多人将typeOf作为练习实施,但很少有人将termOf作为练习实施。