因此我被要求找到以下类型的表达式:
(int -> ((int -> (bool -> int)) -> (bool -> int)))
所以我构造了以下代码来生成(bool - > int)然而,这是困扰我的组合:
(%which (T)
(%typing '(lambda (f)
(lambda (x)
(succ (f (not x)))))
T))
有人能告诉我任何好的规则或方法吗? :)
答案 0 :(得分:1)
就个人而言,我认为当你从类型中删除多余的括号时会变得更加明显(就像非计划者会写出来的那样):
int -> (int -> bool -> int) -> bool -> int
所以你应该编写一个给出三个参数并返回int
的函数。也就是说,解决方案必须以下列形式表达:
lambda n. lambda f. lambda b. ____
但是你怎么填补这个洞?好吧,看看你从参数中获得了什么类型,很容易看到你可以通过将f
应用到n
和b
来将它们插在一起,产生{{1} }。所以:
int
这是一个解决方案。但仔细看一下这个术语就会注意到最里面的lambda实际上可以减少,这给了一个更简单的术语:
lambda n. lambda f. lambda b. f n b
但事实上,这个问题有点堕落,因为返回一个int总是微不足道的。所以最简单的解决方案可能是:
lambda n. lambda f. f n
获得解决方案的一般方案通常是通过对类型结构的简单归纳:如果需要函数,则记下lambda并递归递归。如果你需要一个元组,那么记下一个元组并以其组件递归递进。如果你需要一个原始类型,那么你可以选择一个常量。如果你需要一些你没有的东西(通常是在多态的情况下),那么在范围内寻找一些能给你这样的东西的函数参数。如果该参数本身是一个函数,请尝试递归构造一个合适的参数。
答案 1 :(得分:0)
有一些工具可以从类型派生实现(通过Curry / Howard对应)。一个例子是Djinn。有an introduction,显示了如何从类型生成术语。
您可以了解有关Curry-Howard的更多信息,并将类型到代码工具移植到Scheme?
答案 2 :(得分:0)
关于你问题的具体细节(而不是一般技巧),我可以这样做:
(int -> ((int -> (bool -> int)) -> (bool -> int)))
可以简化为(A -> ((A -> B) -> B))
和A = int
B = (bool -> int)
。这个简化版本很容易构建:
(lambda (a)
(lambda (f)
(f a)))
很容易理解为什么会有效:a
的类型为A
,而f
的类型为(A -> B)
,因此调用(f a)
会导致{B
1}}。要将具体类型放到这些变量中,a
的类型为int
,f
的类型为(int -> (bool -> int))
,结果当然是(bool -> int)
。
因此,现在您需要找到一个合适的函数,其类型为(int -> (bool -> int))
以插入f
参数。这是一个非常简单的例子:
(lambda (n)
(lambda (negate?)
((if negate? - +) n)))
以下是您可以使用这些功能的方法:
> (define (foo a)
(lambda (f)
(f a)))
> (define (bar n)
(lambda (negate?)
((if negate? - +) n)))
> (define baz ((foo 42) bar))
> (baz #t)
-42
> (baz #f)
42
答案 3 :(得分:0)
这是我搜索的解决方案:
(lambda(i) (lambda(f) (lambda(b) (succ((f(succ i))(不是b)))))))
可以通过以下方式确认: (%其中(T) (打字% '(lambda(i) (lambda(f) (lambda(b) (succ((f(succ i))(不是b)))))) T))
Succ确保它是一个整数而不是 - >布尔。