0

Racket has a non-empty-listof contract but no non-empty-hashof contract. Is there a way to build one?

Ben Greenman
  • 1,945
  • 12
  • 22

2 Answers2

0

Predicates can be used as contracts, so:

(define (non-empty-hash? x)
  (and (hash? x)
       (not (hash-empty? x))))

Then you can use non-empty-hash? as your contract.

Ben Greenman
  • 1,945
  • 12
  • 22
0

You can use contract logical operators like and/c and not/c to build the desired form instead of using a predicate function (Similar to the way mutable datatypes are checked for in contract):

Welcome to Racket v8.7 [cs].
> (define (non-empty-hash/c key/c val/c)
     (and/c (hash/c key/c val/c) (not/c hash-empty?)))
> (define/contract x (non-empty-hash/c symbol? number?) (hash))
x: broke its own contract
  promised: (not/c hash-empty?)
  produced: '#hash()
  in: the 2nd conjunct of
      (and/c
       (hash/c symbol? number?)
       (not/c hash-empty?))
  contract from: (definition x)
  blaming: (definition x)
   (assuming the contract is correct)
  at: string:1:17
 [,bt for context]
> (define/contract x (non-empty-hash/c symbol? number?) (hash 'a 1))
> x
'#hash((a . 1))

or just (and/c hash? (not/c hash-empty?)) if you don't want to constrain the key and value types.

Shawn
  • 47,241
  • 3
  • 26
  • 60