使用change-class从数字创建多项式对象
我已经按照 SICP 2.5.3 中描述的方式编写了一个多项式类(除了使用 defclass)。我希望能够无缝地对多项式和常规数字进行加法和乘法,但我无法使更改类接受数字。
我试图通过将类从整数更改为浮点数来简化问题:
(change-class 4 'float)
但这给了我错误:
There is no applicable method for the generic function
#<STANDARD-GENERIC-FUNCTION CHANGE-CLASS (7)>
when called with arguments
(4 #<BUILT-IN-CLASS FLOAT>).
[Condition of type SIMPLE-ERROR]
我从(仅供参考)收到相同形式的错误:
(change-class 4 'polynomial)
我将继续并实现手动转换,但我更喜欢使用内置的 clo 设施。
正如 Xach 指出的,我可以使用强制或浮动将 4 更改为浮动。这是我试图做的一个更简单的例子,并消除我的不同类的更新实例错误的任何可能性。
这是我尝试过的较长版本,但不起作用:
(defclass polynomial ()
((var :accessor var :initarg :var :initform 'x)
(terms :accessor terms :initarg :terms :initform (make-empty-term-list))))
(defmethod update-instance-for-different-class :before ((old number)
(new polynomial)
&key)
(setf (slot-value new 'terms) (adjoin-term (make-term old 0)
(make-empty-term-list))))
(change-class 4 'polynomial)
我仍然收到类似上面示例的错误:
There is no applicable method for the generic function
#<STANDARD-GENERIC-FUNCTION CHANGE-CLASS (7)>
when called with arguments
(4 #<STANDARD-CLASS POLYNOMIAL>).
[Condition of type SIMPLE-ERROR]
I have written a polynomial class along the lines described in SICP 2.5.3 (except using defclass). I would like to be able to seamlessly add and multiply polynomials and regular numbers but I can't make change-class accept a number.
I tried to simplify the problem by changing class from an integer to a float:
(change-class 4 'float)
but that gave me the error:
There is no applicable method for the generic function
#<STANDARD-GENERIC-FUNCTION CHANGE-CLASS (7)>
when called with arguments
(4 #<BUILT-IN-CLASS FLOAT>).
[Condition of type SIMPLE-ERROR]
I get an error of the same form from (fyi):
(change-class 4 'polynomial)
I'm going to go ahead and implement a manual conversion but I would prefer to use the built-in clos facilities.
As Xach points out I could use coerce or float to change 4 to a float. That was intended as a simpler example of what I was trying to do and to remove any possibility of my update-instance-for-different-class being wrong.
Here is the longer version of what I tried that didn't work:
(defclass polynomial ()
((var :accessor var :initarg :var :initform 'x)
(terms :accessor terms :initarg :terms :initform (make-empty-term-list))))
(defmethod update-instance-for-different-class :before ((old number)
(new polynomial)
&key)
(setf (slot-value new 'terms) (adjoin-term (make-term old 0)
(make-empty-term-list))))
(change-class 4 'polynomial)
I still get an error like the example above:
There is no applicable method for the generic function
#<STANDARD-GENERIC-FUNCTION CHANGE-CLASS (7)>
when called with arguments
(4 #<STANDARD-CLASS POLYNOMIAL>).
[Condition of type SIMPLE-ERROR]
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您可以使用 COERCE 或 FLOAT 来执行此操作:
You can use COERCE or FLOAT to do that:
您不能将 CHANGE-CLASS 与数字一起使用。数字不是 CLOS 类的实例。 CHANGE-CLASS 还被认为可以破坏性将实例修改为新类,而不更改原始实例的标识。
我会:
向 CHANGE-CLASS 添加方法来执行您想要的操作
或者编写一个 CHANGE 函数,该函数实现各种自定义强制规则和调用CHANGE-CLASS 用于从一个 CLOS 类到另一个 CLOS 类的任何更改。
You can't use CHANGE-CLASS with numbers. Numbers are not instances of CLOS classes. CHANGE-CLASS is also thought to destructively modify an instance to a new class, without changing the identity of the original instance.
I would either:
add methods to CHANGE-CLASS that does what you want
or write a function CHANGE, that implements various custom coercion rules and calls CHANGE-CLASS for any change from one CLOS class to another CLOS class.