2010-11-20 5 views
3

Je ces deux sources:Clojure Multimethod dispath problème

(ns odo.IComplex) 
(gen-interface 
    :name odo.IComplex 
    :methods [ 
     [getReal [] Double] 
     [getImag [] Double] 
     [getAbs [] Double] 
     [getArg [] Double] 

     [setReal [Double] void] 
     [setImag [Double] void] 
     [setAbs [Double] void] 
     [setArg [Double] void]]) 

(defprotocol PolarComplex 
    (abs [this] [this value]) 
    (arg [this] [this value])) 

(defmulti polar-complex (fn([record abs arg] (class record)))) 

et

(ns odo.Complex 
    (:gen-class 
    :init init 
    :state state 
    :implements [odo.IComplex]) 
    (:use odo.IComplex)) 

(defrecord State [^Double imag ^Double real] 
    Object (toString [self] 
      (str real (if (>= imag 0) " + " " - ") (Math/abs imag) "j" 
      " : " (abs self) " * exp[ " (arg self) " ]")) 

    PolarComplex (abs [self]  (Math/sqrt (+ (* real real) (* imag imag)))) 
       (abs [self value] (polar-complex self value (arg self))) 

       (arg [self]  (Math/atan2 real imag)) 
       (arg [self value] (polar-complex self (abs self) value))) 

(defmethod polar-complex PolarComplex [num abs arg] 
    (assoc num :real (* abs (Math/cos arg)) :imag (* abs (Math/sin arg)))) 

(defn -init [] [[] (atom (State. 0. 0.))]) 
(defn -getImag [self] (:imag @(.state self))) 
(defn -getReal [self] (:real @(.state self))) 
(defn -getAbs [self] (abs @(.state self))) 
(defn -getArg [self] (arg @(.state self))) 

(defn -setImag [self value] (swap! (.state self) assoc :imag value)) 
(defn -setReal [self value] (swap! (.state self) assoc :real value)) 
(defn -setAbs [self value] (swap! (.state self) abs value)) 
(defn -setArg [self value] (swap! (.state self) arg value)) 

(defn -toString [self] (str @(.state self))) 

et je suis assuré que (isa? odo.Complex.State odo.IComplex.PolarComplex) est true

mais quand j'exécute

(doto (odo.Complex.) 
    (.setArg (/ Math/PI 4.)) (.setAbs (Math/sqrt 2)) (println)) 

Je reçois

java.lang.IllegalArgumentException: Aucune méthode dans multiméthode 'polaire complexe' pour la valeur d'expédition: Classe odo.Complex.State

Pouvez-vous me dire pourquoi?

+0

Je sais que cette mise en œuvre de la méthode est inexact, car le protocole PolarComplex ne plan d'accès comme non aux parties réelles garanti en et complexes. Mais c'est une question à propos de contester. – Odomontois

Répondre

1

J'ai découvert que dans le contexte de sa définition, var PolarComplex est lié à la carte contenant des informations sur le protocole, pas à la classe. Ainsi, la mise en œuvre correcte de multiméthode sera

(defmethod polar-complex (:on-interface PolarComplex) [num abs arg] 
    (assoc num :real (* abs (Math/cos arg)) :imag (* abs (Math/sin arg)))) 

ou

(defmethod polar-complex odo.IComplex.PolarComplex [num abs arg] 
    (assoc num :real (* abs (Math/cos arg)) :imag (* abs (Math/sin arg))))