How to force a field of a structure to be of a certain type?

How can I apply the type of fields in this structure?

#lang racket (struct Car (model year)) 

I tried to use a contract (but since I'm new to racquet, this one obviously doesn't work ...: P)

 (provide (contract-out [Car (string? integer? . -> . Car?)])) 

Example: this is successful, but it should not ...

(define my-car (Car 2008 "A3"))

Unfortunately, it seems that nowhere is written how to do this.

+6
source share
1 answer

I think that you will press at least one, and maybe both of them:

  • Using (provide (contract-out ....)) means that the contract is applied only at the module boundary - only for other modules for which require this. Therefore, if your test case was in the same module, the contract will not apply. Instead, you can use define/contract to make the contract applicable to the thing itself, both in the module where it is defined and externally if you provide it.

  • There is a special contract form for struct s in which you specify a contract for each field. What you tried above is a contract only for the constructor function. Although this may be what you want, consider a contract for struct instead.

Combining both actions, you can:

 ;; Define the contract on the struct itself. ;; Contract is used even within this module. (provide car) (define-struct/contract car ([model string?] [year integer?])) 

If you want the contract to be applied only at the border of the module, you should use:

 ;; Define the contract only as `provide`d. ;; Contract is used only for code `require`-ing this module. (provide (contract-out (struct car ([model string?] [year integer?])))) (struct car (model year)) 

ps FWIW in Racket, the common style is not to use the structure name - car not car .


Refresh . To more clearly illustrate the difference:

 #lang racket (module mod racket (provide car0) (define-struct/contract car0 ([model string?] [year integer?])) (car0 "foo" "bar") ;; gives contract violation ;; because contract on struct itself (struct car1 (model year)) (provide (contract-out (struct car1 ([model string?] [year integer?])))) (car1 "foo" "bar") ;; does NOT give contract violation ;; because contract only on the `provide` ) (require 'mod) (car0 "foo" "bar") ;; gives contract violation (car1 "foo" "bar") ;; gives contract violation 
+6
source

Source: https://habr.com/ru/post/946897/


All Articles