3 ;; get a list of coercions (t1->t t2->2 .... tn->t)
4 ;; if a type coercion does not exist, the
5 ;; particular index will have #f
6 (define (get-coercions type types)
10 (get-coercion t type)))
13 (define (all-valid? coercions)
15 ((null? coercions) #t)
16 ((car coercions) (all-valid? (cdr coercions)))
19 (define (get-all-type-coercions types)
21 (get-coercions t types))
24 (define (apply-generic op . args)
25 (define (apply-generic-2 type-coercion-list)
27 ((null? type-coercion-list) (error "cannot find a suitable type coercion"))
28 ((all-valid? (car type-coercion-list))
29 (let ((coerced-args (map (lambda (t a) (t a)) (car type-coercion-list) args)))
30 (apply-generic-1 coerced-args)))
31 (else (apply-generic-2 (cdr type-coercion-list)))))
33 (define (apply-generic-1 args)
34 (let ((type-tags (map type-tag args)))
35 (let ((proc (get op type-tags)))
37 (apply proc (map contents args))
38 (let ((tn->t1 (get-all-type-coercions types)))
39 (apply-generic-2 tn->t1))))))
41 (apply-generic-1 args))
44 The method will fail if say, t2, t3 and t4 can only be coreced into t1 but the call to apply-generic does not have an argument of type t1.
45 Instead, if we have a way to figure out the relation between types and the hierarchy, then we can deal with it better.