SKI转换,如何用函数式语言编程

时间:2011-01-21 07:57:20

标签: functional-programming prolog lambda-calculus

我正面临以下Prolog代码。表达式[X]>> Y代表 对于lambda表达式lambda X.Y.代码消除了lambda 并给出了S,K和I的组合表达式:

convert([X]>>Y,'I') :- X==Y, !.
convert([X]>>Y,apply('K',Y)) :- var(Y), !.
convert([X]>>([Y]>>Z),R) :-
     convert([Y]>>Z,H), convert([X]>>H,R).
convert([X]>>apply(Y,Z),apply(apply('S',S),T)) :-
     convert([X]>>Y,S), convert([X]>>Z,T).
convert([_]>>Y,apply('K',Y)).

以下是一个如何运作的示例:

 ?- convert([X]>>([Y]>>apply(Y,X)),R).
 R = apply(apply('S', apply(apply('S', apply('K', 'S')), 
  apply('K', 'I'))), apply(apply('S', apply('K', 'K')), 'I'))

假设我想在Haskell,ML或中编写相同的转换 类似。我怎样才能做到这一点?我可以使用可用的lambda表达式吗? 在函数式编程语言中直接?或者我必须这样做 退回一些元编程设施?

最好的问候

P.S。:上面的代码不是导致非常短的SKI转换 SKI表达。更好的代码可以检查是否出现 lambda表达式主体中的绑定变量。

2 个答案:

答案 0 :(得分:4)

您的prolog代码几乎可以逐字翻译成ML或Haskell的模式匹配。当然,您需要为lambda表达式定义自己的ADT。对于最佳的组合器组合以及该组合的转换,我建议参考http://www.amazon.com/Functional-Programming-International-Computer-Science/dp/0201192497

答案 1 :(得分:1)

您可以直接使用lamdba表达式。在哈斯克尔:

i x = x
k x = \y -> x
s x y z = x z $ y z

r = s (s (k s) (k i)) (s (k k) i)

-- r 3 (+5) -> 8

(请注意,我不知道SKI最多可以知道,这个片段是将维基百科上的定义直接转换为Haskell;它有效,但请检查它在概念上是否正确)