更具体地说,您可以重载内置的Scheme过程显示吗?
更一般的情况下,如何重载Scheme中的任何过程?
发布于 2013-04-09 14:00:53
Scheme没有基于Java/C++类型的重载,它是动态类型的,所以没有意义。
不过,您可以做一些事情:
您可以根据参数的结构进行重载:
(define overload1
(case-lambda
((x y) (+ x y))
((x y z) (+ (- x y) z))))但这并不能真正帮助您,因为display无论如何都只接受一个参数。
(define (overload-kinda x)
(cond
((list? x) (do-list x))
((symbol? x) (do-sym x))
;etc
))这很麻烦,但有时也是必要的。
我常用的方法是高阶函数和情况下的lambda
(define my-display
(case-lambda
((x) (display x))
((x f) (display (f x)))))现在,如果我们需要特殊的处理来显示任何东西,我们传入一个函数来呈现它。
发布于 2021-03-04 20:37:16
被接受的答案不会重载函数,只定义具有相同行为的不同函数。
方案通常允许重写Monkey Patch函数,所以要重载该函数(例如display),可以使用名为bultin的函数
(define display (let ((orig display))
(lambda (x . rest)
(let ((port (if (null? rest)
(current-output-port)
(car rest))))
(if (number? x)
(orig (string-append "#<" (number->string x 16) ">") port)
(orig x port))))))现在,显示器与数字的工作方式不同了。您还可以使用自定义类型,如以特定方式显示不同类型的记录。这是一个通用的例子,如何在允许修改原始绑定的任何语言中重写bultin函数。你将原始函数保存在变量中,重新定义函数,如果你要调用原始函数,你可以使用保存原始函数的变量。
代码可以抽象为通用宏来重新定义函数,并在特定类型的参数上运行您的代码,因此它将是适当的重载,而不是像case-lambda那样仅基于参数的数量。
下面是这样的宏的例子(使用lisp类型的宏):
(define-macro (overload name-spec . body)
(let ((name (car name-spec))
(args (cdr name-spec)))
`(define ,name (let ((,name ,name))
(lambda ,args
,@body)))))
(overload (display x . rest)
(let ((port (if (null? rest)
(current-output-port)
(car rest))))
(if (number? x)
(display (string-append "#<" (number->string x 16) ">") port)
(display x port))))
(display 10)
;; ==> #<a>
(display "20")
;; ==> 20https://stackoverflow.com/questions/15892214
复制相似问题