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