Generalised to coercion to any of the argumements (ending 2.82)
This commit is contained in:
parent
74050eeb6c
commit
7147075c21
21
2_78.rkt
21
2_78.rkt
|
@ -89,19 +89,27 @@
|
|||
(cond ((null? l) #f)
|
||||
((eq? (car l) '()) #t)
|
||||
(else (any-empty-list (cdr l)))))
|
||||
(define (coerce-args args type-tags)
|
||||
(if (null? type-tags)
|
||||
'()
|
||||
(let* ((type (car type-tags))
|
||||
(coerced-args (map (coerce-to type) args)))
|
||||
(if (not (any-empty-list coerced-args))
|
||||
coerced-args
|
||||
(coerce-args args (cdr type-tags))))))
|
||||
(let ((type-tags (map type-tag args)))
|
||||
(let ((proc (get op type-tags)))
|
||||
(if proc
|
||||
(apply proc (map contents args))
|
||||
(if (> (length args) 1)
|
||||
(let* ((type1 (car type-tags))
|
||||
(coerced-args (map (coerce-to type1) args)))
|
||||
(if (not (any-empty-list coerced-args))
|
||||
(let ((coerced-args (coerce-args args type-tags)))
|
||||
(if (not (null? coerced-args))
|
||||
(apply apply-generic (cons op coerced-args))
|
||||
(error "Tried coercing all args to first type"
|
||||
(error "Can't coerce arguments to a common type"
|
||||
(list op type-tags))))
|
||||
(error "Too few args"))))))
|
||||
|
||||
|
||||
;; map coerce-to onto all arguments for the type of each argument.
|
||||
;; The first one that returns all non empty arguments is the coercion
|
||||
;; that is used.
|
||||
|
@ -365,3 +373,8 @@
|
|||
;; b: If the arguments are of the same type, and if there isn't an operation defined for
|
||||
;; that combination of arguments, then apply-generic will try to coerce a type to itself,
|
||||
;; so there is a need change it.
|
||||
|
||||
;; 2.82: The approach of coercing to a common type would not work where there is a function
|
||||
;; that takes mixed types. For example, if we have an operator to add a complex to a rational.
|
||||
;; It isn't possible to coerce from one to the other, so a mixed-type operator is needed, and this
|
||||
;; approach would fail.
|
||||
|
|
Loading…
Reference in New Issue