有人可以尝试解释这两个函数:球拍中PLAI方案中的“define-type”和“type-case”吗?我是一个菜鸟程序员,我不太了解球拍网站上的文档。如果有人能举例,我们将不胜感激。谢谢。
答案 0 :(得分:3)
以下是如何使用define-type
和type-case
的一个小例子:
#lang plai
; A ListOfNumbers are either
; is either an empty list of numbers
; or is constructed to two things a, and, d,
; where a is a number and d is a list of numbers.
(define-type ListOfNumbers
(Empty)
(Cons (a number?) (d ListOfNumbers?)))
; construct a list of numbers as an example
(define a-list (Cons 42 (Cons 43 (Empty))))
a-list ; prints: (Cons 42 (Cons 43 (Empty)))
(type-case ListOfNumbers a-list
(Empty () "the list is empty")
(Cons (a d) (~a "the first number in the list is " a)))
; prints: "the first number in the list is 42"
答案 1 :(得分:1)
我对 Lisp/Scheme/Racket 的经验不是很丰富,但看起来这个问题在 5 年后仍然没有答案,所以我会试一试。
首先,请注意并非一切都是函数。例如,当您使用 define
来定义一个函数或某个其他值时,define
不会作为一个函数运行。函数是接受一些输入,然后返回一些输出的东西。 define
不这样做。相反,它会改变您正在编程的环境,从而产生一个可用于引用某个值的新名称。
例如,在...
(define cadr
(lambda (x)
(car (cdr x))))
... define
修改了编程环境,以便函数 cadr
现在存在。 cadr
是一个函数(如果你用一些输入调用它,它会产生一些输出),但 define
本身不是一个函数(你不是用一些输入调用 define
以获得一些输出)。
希望消除这种区别后,define-type
不是函数。它与 define
类似,因为它修改了编程环境以使其具有新名称来引用某些值。它用于定义新类型,以及一些允许您使用该类型的函数。
取自 Racket 文档的示例:
> (define-type Shape
[circle (radius : number)]
[rectangle (width : number)
(height : number)])
> (define (area [s : Shape])
(type-case Shape s
[circle (r) (* (* r r) 3.14)]
[rectangle (w h) (* w h)]))
> (area (circle 1))
- number
3.14
> (area (rectangle 2 3))
- number
6
这里定义了一个新类型 Shape
,它说它有两个变体:circle
和 rectangle
。它进一步说,在 circle
变体的情况下,有趣的数据是它的 radius
,它是一个数字;而在 rectangle
变体中,有两条数据(或“字段”),它们是它的 width
和 height
(都是数字)。
然后它定义了一个新函数 area
,它应该接受类型为 Shape
(我们刚刚声明的类型)的单个输入。 type-case
表达式用于指定如何根据我们正在处理的变体计算 Shape
的面积。如果我们正在处理 circle
,那么我们可以通过平方半径并将其乘以 Pi 来计算面积。如果我们处理的是 rectangle
,那么我们可以通过将其宽度乘以高度来计算面积。
之前,我说过 define-type
不是函数,但通过使用它,它定义了一个新类型和一堆允许我们使用该类型的函数。那么它定义的这些新功能是什么呢?看这个例子:
> (define c (circle 10))
> c
- Shape
(circle 10)
> (circle? c)
- boolean
#t
> (circle-radius c)
- number
10
> (define r (rectangle 2 3))
> (+ (rectangle-width r) (rectangle-height r))
- number
5
这里我们然后使用 define
来修改编程环境,以便名称 c
指代我们创建的半径为 10 的圆。circle?
是一个函数,当我们在前面的例子中做了 define-type
,它返回我们正在处理的 shape
是否是一个 circle
变体(而不是一个 rectangle
变体)。类似地,circle-radius
、rectangle-width
和 rectangle-height
函数是在我们使用 define-type
时自动为我们定义的,它们允许我们访问数据类型内部的字段。>