2016-08-31 4 views
2

共通のlispでバイナリ検索ツリーを構築しようとしています。私はこのようなCLOSを使用してバイナリ検索クラスを定義しています2つの引数で汎用関数(マルチメソッド)を特化する

(defclass bst() 
    ((root :type node 
     :accessor tree-root 
     :initform nil 
     :initarg root))) 

ツリーがキーとゼロが含まれている場合、私は木のオブジェクトとキーに取り、ブール値trueを返す汎用的な関数を定義しようとしていますツリーにキーが含まれていない場合

今私は、一般的な機能の次の定義を持っている:私はREPLにファイルをロードする際に

(defgeneric contains ((tree bst) (key)) 
    (:documentation "returns boolean of whether the given tree contains a particular key) 

は、私は(私はSBCLを使用しています)、次のエラーを取得:

Required argument is not a symbol: (TREE BST) 

ジェネリック関数の仕組みを誤解していますか?私は関数を適切に定義することはできません。

+8

型シグネチャは、メソッドに行くべきではなく、 'DEFGENERIC'

は、次のいずれかが必要です。 – jkiiski

+0

ちょっとしたメモ: '<...>:initarg root'は' <...>:initarg:root': ':root'はここのキーワードにする必要があります。 – mobiuseng

+2

@mobiuseng、ちょうどペントントを弾く:) initargsがキーワードシンボルであることは非常に一般的ですが、必要ではありません。キーワード以外の記号は名前の衝突を避けるのに役立ち、内部の記号は「行っていることがわからない限りこれを使用しないでください」を示すのに役立ちます。 –

答えて

9

はい、defgenericは汎用関数を定義します。方法は、defgenericへの呼び出し、またはdefmethodへの呼び出しで指定できます。

(defgeneric contains (tree key) 
    (:documentation "returns boolean of whether the given tree contains a particular key") 
    (:method ((tree bst) key) ...)) 

か::

(defgeneric contains (tree key) 
    (:documentation "returns boolean if a given tree contains a given key")) 

(defmethod contains ((tree bst) key) 
    ...) 
+0

あなたは「どちらか」と書いています...それは私がこれら2つのアプローチを混ぜ合わせることができないことを意味しますか? –

+1

@DanielJourできますが、私の記憶によれば、再定義時に起こることは実装仕様になると言われています。メソッドとクラスを完全に制御している限り、特定の汎用関数のメソッドを定義する2つの方法のうちの1つに従ってください。それ以外の場合は、 'defmethod'を使います。私は通常、 'defgeneric'でメソッドを指定するのではなく、' defmethod'を使用します。 – Vatine

関連する問題