Создайте полиномиальный объект из числа, используя класс изменения.

StackOverflow https://stackoverflow.com/questions/2532998

  •  22-09-2019
  •  | 
  •  

Вопрос

Я написал полиномиальный класс по принципу, описанному в 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)

Я собираюсь реализовать преобразование вручную, но предпочитаю использовать встроенные средства закрытия.

Как указывает Ксач, я мог бы использовать принуждение или плавающее число, чтобы изменить 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]
Это было полезно?

Решение

Вы не можете использовать CHANGE-CLASS с числами.Числа не являются экземплярами классов CLOS.СМЕНА КЛАССА также считается разрушительно изменить экземпляр на новый класс, не меняя идентичность исходного экземпляра.

Я бы либо:

  • добавьте методы в CHANGE-CLASS, которые делают то, что вы хотите

  • или напишите функцию CHANGE, которая реализует различные пользовательские правила приведения и вызывает CHANGE-CLASS для любого изменения одного класса CLOS на другой класс CLOS.

Другие советы

Для этого вы можете использовать COERCE или FLOAT:

(float 4) => 4.0
(coerce 4 'float) => 4.0
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top