On this page:
2.1 Comparison Predicate Generation
define-comparison-predicates
8.12

2 Typed Utilities🔗ℹ

2.1 Comparison Predicate Generation🔗ℹ

 (require typed/alexis/util/comparator)
  package: alexis-util

See also alexis/util/comparator for untyped Racket forms.

syntax

(define-comparison-predicates
  predicate-base-id : predicate-args-type
  comparator-expr maybe-adapter)
 
maybe-adapter = 
  | #:adapter adapter-expr : adapter-args-type
This provides a convenient macro for generating comparison predicates based on a "comparator" function. The provided comparator-expr must evaluate to a function which takes two values and produces either 0, 1, or -1. These values correspond to both parameters being equal, the first parameter being greater, or the second parameter being greater, respectively. The predicate-args-type must also be explicitly provided, which describes the types of values that are permitted to be passed to the predicates.

Using this function, a set of functions is generated using predicate-base-id as a base identifer to determine the names of the resulting definitions. This macro produces six functions, their names acquired by appending =?, >?, <?, <>?, >=?, and <=? to predicate-base-id.

If adapter-expr is provided, then it must evaluate to a function that takes a single parameter and returns a single value. If specified, values will be threaded through adapter-expr before being passed to comparator-expr. This allows values to be mapped to other values before being provided to the comparator for additional processing or parsing. The adapter-args-type expression must specify a type that describes the values that may be passed to the adapter function.

Examples:
> (struct num-str ([num : Real] [str : String]))
> (: num-str-compare (num-str num-str -> (U -1 0 1)))
> (define (num-str-compare a b)
    (if (= (num-str-num a) (num-str-num b))
        (let ([a (num-str-str a)]
              [b (num-str-str b)])
          (cond
            [(string>? a b)  1]
            [(string<? a b) -1]
            [else            0]))
        (let ([a (num-str-num a)]
              [b (num-str-num b)])
          (cond
            [(> a b)  1]
            [(< a b) -1]
            [else     0]))))
> (define-comparison-predicates
    num-str : (Pairof Real String) num-str-compare
    #:adapter (λ (p) (num-str (car p) (cdr p))) : num-str)

/home/root/user/.local/share/racket/8.12/pkgs/alexis-util/ty

ped/alexis/util/comparator.rkt:33:15: Type Checker: missing

type for identifier;

 consider adding a type annotation with `:'

  identifier: compare

  in: compare

> (num-str=? '(123 . "abc") '(123 . "abc"))

eval:6:0: Type Checker: missing type for top-level

identifier;

 either undefined or missing a type annotation

  identifier: num-str=?

  in: "abc"

> (num-str<? '(200 . "aaa") '(100 . "aaa"))

eval:7:0: Type Checker: missing type for top-level

identifier;

 either undefined or missing a type annotation

  identifier: num-str<?

  in: "aaa"

The typed/alexis/util/comparator module also exports comparison-predicates-out from alexis/util/comparator, which is compatible with Typed Racket.