从类型方案构造表达式

时间:2012-05-26 09:34:09

标签: types scheme expression

因此我被要求找到以下类型的表达式:

(int -> ((int -> (bool -> int)) -> (bool -> int)))

所以我构造了以下代码来生成(bool - > int)然而,这是困扰我的组合:

(%which (T)
        (%typing '(lambda (f)
                    (lambda (x)
                      (succ (f (not x)))))
                 T))

有人能告诉我任何好的规则或方法吗? :)

4 个答案:

答案 0 :(得分:1)

就个人而言,我认为当你从类型中删除多余的括号时会变得更加明显(就像非计划者会写出来的那样):

int -> (int -> bool -> int) -> bool -> int

所以你应该编写一个给出三个参数并返回int的函数。也就是说,解决方案必须以下列形式表达:

lambda n. lambda f. lambda b. ____

但是你怎么填补这个洞?好吧,看看你从参数中获得了什么类型,很容易看到你可以通过将f应用到nb来将它们插在一起,产生{{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的类型为intf的类型为(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确保它是一个整数而不是 - >布尔。