Crie um objeto polinomial a partir de um número usando a classe de alteração
-
22-09-2019 - |
Pergunta
Escrevi uma classe polinomial ao longo das linhas descritas no SICP 2.5.3 (exceto usando o DEFClass). Eu gostaria de poder adicionar e multiplicar perfeitamente os polinômios e números regulares, mas não posso fazer com que a classe mude aceite um número.
Tentei simplificar o problema alterando a classe de um número inteiro para um flutuador:
(change-class 4 'float)
Mas isso me deu o erro:
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]
Recebo um erro da mesma forma de (FYI):
(change-class 4 'polynomial)
Vou seguir em frente e implementar uma conversão manual, mas preferiria usar as instalações de fechamento embutidas.
Como Xach aponta, eu poderia usar coerce ou flutuar para mudar 4 para um flutuador. Isso pretendia como um exemplo mais simples do que eu estava tentando fazer e remover qualquer possibilidade de estar errado a minha classe de atualização-instância por diferença.
Aqui está a versão mais longa do que eu tentei que não funcionou:
(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)
Ainda recebo um erro como o exemplo acima:
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]
Solução
Você não pode usar a classe de troca com números. Os números não são instâncias de classes de fechamento. Pensa-se também na classe de mudança destrutivamente Modifique uma instância para uma nova classe, sem alterar a identidade da instância original.
Eu também:
Adicione métodos à classe de mudança que faz o que você deseja
Ou escreva uma alteração de função, que implementa várias regras de coerção personalizadas e chama a classe de alteração para qualquer alteração de uma classe Clos para outra classe Clos.
Outras dicas
Você pode usar coerce ou flutuar para fazer isso:
(float 4) => 4.0
(coerce 4 'float) => 4.0