(module contracts mzscheme
(require (lib "contract.ss")
(lib "etc.ss")
(lib "list.ss")
(lib "67.ss" "srfi"))
(define equality/c (any/c any/c . -> . boolean?))
(define hash-fn/c (any/c . -> . integer?))
(define comparison/c (any/c any/c . -> . (integer-in -1 1)))
(define (listof-unique/c equ?)
(flat-named-contract "list of unique elements"
(lambda (elems)
(recur scan ([elems elems])
(if (null? elems)
#t
(let* ([elem (car elems)]
[rest (cdr elems)])
(and (andmap (lambda (other) (not (equ? elem other))) rest)
(scan rest))))))))
(define (listof-unique-compare/c cmp)
(flat-named-contract "list of unique elements"
(lambda (elems)
(apply chain<? cmp (sort elems (<? cmp))))))
(provide/contract
[equality/c contract?]
[hash-fn/c contract?]
[comparison/c contract?]
[listof-unique/c (equality/c . -> . flat-contract?)]
[listof-unique-compare/c (comparison/c . -> . flat-contract?)])
)