Структура, которая принимает только логические значения - PullRequest
0 голосов
/ 27 февраля 2019

Как бы я сделал структуру, которая принимает значение, только если оно логическое

(struct mystruct [val]  //only take val if it's a boolean )

Ответы [ 2 ]

0 голосов
/ 27 февраля 2019

Существует как минимум 3 способа:

  1. Определить структуру с контрактом, используя define-struct/contract.

  2. Определите структуру с охраной, используя struct с #:guard.

    a) Охрана, которая использует контракт с struct-guard/c.

    b) Защита, определенная вручную с помощью unless, boolean?, raise-argument-error.

  3. Напишите вашу программу в Типизированная ракетка вместоРакетка, и используйте такой тип, как Boolean.

1: Структура с контрактом

Вы можете использовать define-struct/contract следующим образом:

(define-struct/contract mystruct ([val boolean?]))

Правильно и неправильно его использовать:

> (define xt (mystruct #true))
> (define xf (mystruct #false))
> (mystruct-val xt)
#true
> (mystruct-val xf)
#false
> (mystruct 3)
make-mystruct: contract violation
  expected: boolean?
  given: 3
  in: the 1st argument of
      (-> boolean? symbol? any)
  contract from: (struct mystruct)
  blaming: .../so-54901923.rkt
   (assuming the contract is correct)

2: построить с защитой

Вы можете использовать ключевое слово #:guard из struct как это:

(struct mystruct [val]
  #:guard <guard-procedure>)

Самый простой способ определить защитную процедуру - это использовать библиотечную функцию, например struct-guard/c на снимке Racket HEAD (не в 7.2, будет выпущен в следующей версии Racket).

(struct mystruct [val]
  #:guard (struct-guard/c boolean?))

Использование, правильное и правильноеctly:

> (define xt (mystruct #true))
> (define xf (mystruct #false))
> (mystruct-val xt)
#true
> (mystruct-val xf)
#false
> (mystruct 3)
mystruct: contract violation
  expected: boolean?
  given: 3
  in: boolean?
  contract from: 
      .../so-54901923.rkt
  blaming: .../so-54901923.rkt
   (assuming the contract is correct)

Если вам недоступно что-то вроде struct-guard/c или если вам нужно больше мощности / контроля, чем обеспечивает struct-guard/c, вы можетеопределить защитную процедуру вручную.Если структура имеет n полей, сторожевая процедура должна принимать n + 1 аргументов, соответствующих полям плюс имя структуры.

Например, для вашегоmystruct, это должна быть функция, которая принимает значение поля val и имя:

(lambda (val name)
  ???)

Защитная процедура должна возвращать результат с несколькими значениями, используя n значения, соответствующие полям.

(lambda (val name)
  (values val))

И он может запускать произвольные проверки значений перед их передачей:

(lambda (val name)
  (unless (boolean? val)
    (raise-argument-error name "boolean" val))
  (values val))

Помещая его как #:guard:

(struct mystruct [val]
  #:guard (lambda (val name)
            (unless (boolean? val)
              (raise-argument-error name "boolean" val))
            (values val)))

Использование:

> (define xt (mystruct #true))
> (define xf (mystruct #false))
> (mystruct-val xt)
#true
> (mystruct-val xf)
#false
> (mystruct 3)
mystruct: contract violation
  expected: boolean
  given: 3

3: набранная ракетка

Можно использовать #lang typed/racket.Его struct форма имеет тип для каждого поля:

#lang typed/racket

(struct mystruct ([val : Boolean]))

Используя его:

> (define xt (mystruct #true))
> (define xf (mystruct #false))
> (mystruct-val xt)
- : Boolean
#true
> (mystruct-val xf)
- : Boolean
#false
> (mystruct 3)
Type Checker: type mismatch
  expected: Boolean
  given: Positive-Byte in: 3
0 голосов
/ 27 февраля 2019

Вы пробовали?

#lang typed/racket

(struct point ([q : Boolean] [x : Real] [y : Real]))

http://docs.racket -lang.org / ts-guide / quick.html #% 28part. .Использование .Typed_.Racket_from_the_.Racket_.REPL% 29

...