3

有人可以尝试解释这两个功能:球拍PLAI方案中的“定义类型”和“类型案例”吗?我是一个菜鸟程序员,我不太了解球拍网站上的文档。如果有人可以提供示例,将不胜感激。谢谢。

4

2 回答 2

3

下面是一个如何使用define-typeand的小例子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"
于 2015-10-26T18:30:01.550 回答
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,它说它有两个变体:circlerectangle. 它进一步说,在circle变体的情况下,有趣的数据是它的radius,它是一个数字;在rectangle变体中,有两条数据(或“字段”),分别是它的widthheight(两个数字)。

然后它定义了一个新的函数area,它应该接受一个类型的输入Shape(我们刚才声明的类型)。该type-case表达式用于指定如何Shape根据我们正在处理的变体来计算 a 的面积。如果我们正在处理 acircle那么我们可以通过将半径平方并乘以 Pi 来计算面积。如果我们正在处理 a 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?时自动创建的函数,它返回我们是否正在处理with 是一个变体(与变体相反)。类似地,当我们使用 时,会自动为我们定义和函数,这允许我们访问数据类型内部的字段。define-typeshapecirclerectanglecircle-radiusrectangle-widthrectangle-heightdefine-type

于 2021-04-03T21:43:24.013 回答