Creare un oggetto polinomiale da un numero utilizzando il cambiamento di classe
-
22-09-2019 - |
Domanda
ho scritto una classe polinomiale lungo le linee descritte nel SICP 2.5.3 (tranne usando defclass). Mi piacerebbe essere in grado di aggiungere senza soluzione di continuità e moltiplicare polinomi e numeri regolari, ma non riesco a fare il cambiamento di classe accettare un numero.
Ho cercato di semplificare il problema modificando classe da un intero ad un galleggiante:
(change-class 4 'float)
, ma che mi ha dato l'errore:
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]
ottengo un errore della stessa forma da (FYI):
(change-class 4 'polynomial)
ho intenzione di andare avanti e realizzare una conversione manuale, ma io preferirei di utilizzare le strutture clos built-in.
Come Xach sottolinea che potevo usare costringere o galleggiare per cambiare 4 ad un galleggiante. Che è stato inteso come un esempio più semplice di quello che stavo cercando di fare e di togliere ogni possibilità di mio aggiornamento istanza-per-diverso-class essere sbagliato.
Questa è la versione più lungo di quello che ho provato che non ha funzionato:
(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)
Ancora ottengo un errore come nell'esempio precedente:
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]
Soluzione
Non è possibile utilizzare CAMBIO-CLASS con i numeri. I numeri non sono istanze di classi CLOS. CHANGE-CLASS è anche pensato per distruttivo modificare un esempio per una nuova classe, senza cambiare l'identità dell'istanza originale.
I dovrebbero o:
-
aggiungere metodi per modificare-CLASS che fa quello che si desidera
-
o scrivere un cambiamento di funzione, che implementa le regole di coercizione vari personalizzati e chiama CHANGE-CLASS per qualsiasi cambiamento da una classe ad un'altra classe CLOS CLOS.
Altri suggerimenti
È possibile utilizzare costringere o FLOAT per farlo:
(float 4) => 4.0
(coerce 4 'float) => 4.0