Skip to content

Instantly share code, notes, and snippets.

@takikawa
Created October 13, 2012 15:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save takikawa/3885002 to your computer and use it in GitHub Desktop.
Save takikawa/3885002 to your computer and use it in GitHub Desktop.
Generics example from RacketCon 2012
#lang racket
;; Example code from RacketCon 2012
(require racket/generic)
;; simple set interface
(define-generics set
(set-add elem set)
(set-contains? elem set)
(set-empty? set)
;; #:defaults work in our experimental branch of Racket
;; they will work in a future release of Racket
#|
#:defaults
([(list?) (set-add cons)
(set-contains? member)
(set-empty? empty?)])
|#
)
;; implement a simple set using a hash
(struct my-set (hash)
#:methods gen:set
[(define (set-add elem set)
(my-set (hash-set (my-set-hash set) elem #t)))
(define (set-contains? elem set)
(my-set (hash-ref (my-set-hash set) elem #f)))
(define (set-empty? set)
(null? (hash-keys (my-set-hash set))))])
(define mt-set (my-set (hash)))
(set-contains? 5 (set-add 5 mt-set))
;; without #:defaults, we can still use a trick:
(define (-set-add elem set)
(cond [(list? set) (cons elem set)]
[else (set-add elem set)]))
(define (-set-contains? elem set)
(cond [(list? set) (member elem set)]
[else (set-contains? elem set)]))
(define (-set-empty? set)
(cond [(list? set) (null? set)]
[else (set-empty? set)]))
;; some contracts
(define int-set/c
(recursive-contract
(set/c [set-add (-> integer? int-set/c int-set/c)]
[set-contains? (-> integer? int-set/c any)]
[set-empty? (-> int-set/c any)])))
(define/contract a-set int-set/c (set-add 5 mt-set))
;; passes contract
(set-add 5 a-set)
;; produces a contract error as expected
#;
(set-add "foo" a-set)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment