Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I force the field of a struct to be of some type?

Tags:

racket

How can I enforce the type of the fields in this struct?

#lang racket
(struct Car (model year))

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

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

Example: This succeds but it shouldn't...

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

Sadly, it doesn't seem to be written anywhere how to get this done.

like image 553
TesX Avatar asked Jun 09 '13 16:06

TesX


People also ask

What is the difference between a struct and a single field?

All fields can have different types of data whereas a single field should have some type of data. The keyword used for a structure in Matlab is “struct” Array of a structure is also possible in Matlab. A struct can have a single field, many fields, and even no field.

How many fields can be added to a struct?

A struct can have a single field, many fields, and even no field. It can be one dimensional or multi-dimensional. Value to the structure can be added using a structure name and filedname connected with the dot operator.

What is structtype and structfield in pyspark?

PySpark PySpark StructType & StructField classes are used to programmatically specify the schema to the DataFrame and creating complex columns like nested struct, array and map columns. StructType is a collection of StructField’s that defines column name, column data type, boolean to specify if the field can be nullable or not and metadata.

How do you add values to an a struct in C++?

A struct can have a single field, many fields, and even no field. It can be one dimensional or multi-dimensional. Value to the structure can be added using a structure name and filedname connected with the dot operator. Character values should be added using ‘ ‘ whereas numerical value can be added as it is.


1 Answers

I think you're hitting at least one, and maybe both of the following:

  1. Using (provide (contract-out ....)) means the contract applies only at the module boundary -- only for other modules that require this one. So if your test example was in the same module, the contract would not apply. Instead you can use define/contract to make a contract apply to the thing itself, both in the module where it is defined and outside if you provide it.

  2. There is a special form of contracts for structs, in which you specify a contract for each field. What you tried above is a contract just on the constructor function. Although that could be what you want, consider using the contract for the struct instead.

Combining both you could do:

;; 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 did want the contract to apply only at the module boundary, then you would 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))

p.s. FWIW in Racket the common style is not to capitalize a struct name -- car not Car.


Update: Just to illustrate the difference more clearly:

#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
like image 120
Greg Hendershott Avatar answered Nov 09 '22 20:11

Greg Hendershott