仅接受布尔值的结构

时间:2019-02-27 09:21:45

标签: racket

我如何制作仅包含布尔值的结构

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

2 个答案:

答案 0 :(得分:2)

至少有3种方式:

  1. 使用define-struct/contract通过合同定义结构。

  2. 使用struct#:guard来定义带有防护的结构。

    a)使用与struct-guard/c签约的后卫。

    b)使用unlessboolean?raise-argument-error手动定义的防护。

  3. 使用Typed Racket而不是Racket编写程序,并使用类似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:守卫结构

您可以像这样使用struct#:guard关键字:

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

定义保护程序的最简单方法是在Racket HEAD快照上使用类似struct-guard/c的库函数(不包含在7.2中,要在下一版的Racket中发布)。

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

正确和错误地使用它:

> (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

答案 1 :(得分:0)

您尝试过吗?

#lang typed/racket

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

http://docs.racket-lang.org/ts-guide/quick.html#%28part..Using.Typed_.Racket_from_the_.Racket_.R.E.P.L%29