Reputation: 323
Can someone try and explain these two functions: "define-type" and "type-case" in the PLAI scheme in racket? I'm a noob programmer and I don't really understand the documentation on the racket website. If anyone could provide examples, it would greatly be appreciated. Thanks.
Upvotes: 3
Views: 2954
Reputation: 83
I'm not super experienced with Lisp/Scheme/Racket, but it looks like this question is still unanswered after 5 years, so I'll give it a shot.
First of all, note that not everything is a function. For example, when you use define
to define a function or some other value, define
is not acting as a function. A function is something that takes some input, and then returns some output. define
does not do this. Instead, it changes the environment that you're programming in such a way that a new name exists that can be used to refer to some value.
So for example, in...
(define cadr
(lambda (x)
(car (cdr x))))
... define
modifies the programing environment so that the function cadr
now exists. cadr
is a function (if you invoke it with some input, it will yield some output), but define
itself is not a function (you're not invoking define
with some input in order to get some output).
With that distinction hopefully cleared up, define-type
is not a function. It is similar to define
in that it modifies the programming environment to make it so that you have new names to refer to certain values. It is used to define a new type, along with some functions the allow you to work with that type.
An example taken from the Racket documentation:
> (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
Here it defines a new type Shape
which it says has two variants: circle
and rectangle
. It further says that in the case of the circle
variant, the interesting piece of data is its radius
, which is a number; and in the rectangle
variant, there's two pieces of data (or "fields"), which are its width
and height
(both numbers).
It then defines a new function area
, which is expected to take a single input of type Shape
(the type we just declared earlier). The type-case
expression is used to specify how to compute the area of a Shape
depending on which variant we're dealing with. If we're dealing with a circle
then we can compute the area by squaring the radius and multiplying it by Pi. If we're dealing with a rectangle
, then we can compute the area by multiplying its width by its height.
Earlier, I said define-type
is not a function, but by virtue of using it, it defines a new type and a bunch of functions that allow us to work with that type. So what are these new functions it defines? See this example:
> (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
Here we then use define
to modify the programming environment so that the name c
refers to a circle we created with radius 10. circle?
is a function that automatically got created when we did the define-type
in the earlier example, and it returns whether or not the shape
we're dealing with is a circle
variant (as opposed to a rectangle
variant). Similar, the circle-radius
, rectangle-width
and rectangle-height
functions were automatically defined for us when we used define-type
, which allow us to access the fields inside of the data type.
Upvotes: 2
Reputation: 31145
Here is a little example of how to use define-type
and 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"
Upvotes: 3