[racket] Type-class-like idiom in Racket?
> I see that Racket has generic functions, but they see to work a bit
> differently that CLOS-style generics. Further, like Haskell's type-classes
> I would like to be able to provide a contract for functions that take a
> Listable type:
Racket provides a general mechanism to associate properties to
structure types. These structure type properties,
http://docs.racket-lang.org/reference/structprops.html#(tech._structure._type._property)
allow a structure to define behavior in an extensible way.
For example,
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
#lang racket
;; Define a protocol for speaking.
(define-values (prop:speak prop:speak? prop:speak-ref)
(make-struct-type-property 'speak))
(struct cat ()
#:property prop:speak (lambda (x) (printf "Meow\n")))
(struct bird ()
#:property prop:speak (lambda (x) (printf "Chirp\n")))
(struct person (name)
#:property prop:speak (lambda (x) (printf "Hi, I'm ~a\n" (person-name x))))
(define (doolittle! entity)
(cond
[(prop:speak? entity)
(printf "~a says: " entity)
((prop:speak-ref entity) entity)]
[else
(raise-type-error 'speak! "speaking animal" entity)]))
(doolittle! (cat))
(doolittle! (bird))
(doolittle! (person "Danny"))
(doolittle! 'rock)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
In this way, we can define interfaces and implementation of those
interfaces, without the need for class infrastructure.