Hi Matthias,
It appeared to be easy to adapt check-duplicates according to your
suggestion:
(define (check-duplicates items
[same? equal?]
#:key [key values]
#:not-found [not-found #f])
original code,
but calling check-duplicates/t and check-duplicates/list
with extra argument not-found)
(define (check-duplicates/t items key table default)
(let loop ([items items])
(cond
((null? items)
default)
(else
(define key-item (key (car items)))
(cond
((hash-ref table key-item #f)
(car items))
(else
(hash-set! table key-item #t)
(loop (cdr items))))))))
(define (check-duplicates/list items key same? not-found)
body modified like in check-duplicates/t)
(define not-found (gensym))
(check-duplicates '(#f #f) #:not-found not-found) -> #f
(check-duplicates '(#f #t) #:not-found not-found) -> g14494
(check-duplicates '(#f #f) ) -> #f
(check-duplicates '(#f #t) ) -> #f
Another option can be to require (or allow) a thunk for argument not-found
(like in hash-ref),
to call this thunk when appropriate and to return the value(s) returned by
the thunk.
In addition an optional key-word-argument #:found [found values] can be
added
in order to return (found duplicate) when a duplicate is found.
Many more options are open.
One of the most difficult things when designing a program (or procedure or
whatever)
is to make decisions which options the design should offer
always keeping in mind what the users may or may not want (MHO)
Thanks again, Jos
-----Original Message-----
From: Matthias Felleisen [mailto:
matt...@ccs.neu.edu]
Sent: viernes, 27 de mayo de 2016 1:24
To: Jos Koot
Cc: Racket Users
Subject: Re: [racket-users] check-duplicates
You can add a keyword argument that changes the not-found result for such a
case:
(define special (gensym))
(check-duplicates+ '(#f #f) #:not-found special)
Its signature would have to look like this then:
;; check-duplicates : (listof X)
;; [(K K -> bool)]
;; #:key (X -> K)
;; -> X or #f
(define (check-duplicates items
[same? equal?]
#:not-found [default #f]
#:key [key values])
.)
This way the existing interface works but someone who needs it for a list of
Booleans (or something else I can't think of right now) can get a distinct
answer.
[[ Racket's universal type lacks true option types, and we tend to
approximate it with (U #f X). ]]
- Matthias
snip