0

反射群を扱う汎用コードを書きたいので、数学的構造 (ベクトル空間、アフィン空間など) を反映するいくつかの型を設定する必要があります。これらの構造を忠実に型に反映したいので、ある種のパラメトリック型を定義する方法が必要です。

特に、次のコードを記述できるようにしたいと思います

(defclass RealVectorSpace ()
  ((V :accessor underlying-set
      :type Set)
   (vector-add :accessor add
               :type (function ((set-as-type V) (set-as-type V)) (set-as-type V)))
   (scalar-mult :accessor s-mult
                :type (function (real (set-as-type V)) (set-as-type V)))

これは、トリプル (V vector-add スカラー) によって与えられる新しい型 RealVectorSpace を指定する必要があります。ここで、V は何でもかまいません。vector-add は、型 V の何かに評価される型 V (sic) の 2 つのパラメーターを取る関数です。 .

もちろん、この型は実際のベクトル空間の概念を忠実に反映したものではありません。これは、vector-add と scalar-mult がさらにいくつかのプロパティを満たす必要があるためです。しかし、上記の「夢」を実際のコードに変えることさえできません。

編集: sds の回答に応えて、元の質問の次の説明を進めさせてください: 一言で言えば、Lisp には依存型が必要なようです。これは、パラメトリック クラスだけを要求するのとは異なります。実際、Haskell にはパラメトリック型がありますが、従属型はありません (少なくとも組み込み型ではありません)。たとえば、Haskell に依存型がないことについては、こちらで説明しています。

1. 私の夢をコード化するのを手伝ってくれる人はいますか?

2. Lisp マクロのおかげで、Lisp ではパラメトリック クラスは必要ないという話をどこかで聞いたことがあります。それが本当なら、Common Lisp でパラメトリック クラスを実装/偽造するために defmacro を使用する方法を誰か説明できますか?

4

3 に答える 3

3

あなたが望んでいることはあまり理にかなっているとは思えませんが、マクロの (乱用) 使用の例として、次のようにします。

(defmacro define-real-vector-space (type &optional name)
  `(defclass ,(or name (intern (format nil "REAL-VECTOR-SPACE-~A" type))) ()
     ((V :reader underlying-set :initform ',type)
      (vector-add :accessor add
                  :type (function ((x ,type) (y ,type)) => ,type))
      (scalar-mult :accessor s-mult
                   :type (function ((x real) (v ,type) => ,type))))))
;; sample underlying set:
(deftype 3d () (array real (3)))
;; use it:
(macroexpand-1 '(define-real-vector-space 3d))
==>
(DEFCLASS REAL-VECTOR-SPACE-3D NIL
 ((V :READER UNDERLYING-SET :INITFORM '|3D|)
  (VECTOR-ADD :ACCESSOR ADD :TYPE (FUNCTION ((X |3D|) (Y |3D|)) => |3D|))
  (SCALAR-MULT :ACCESSOR S-MULT :TYPE #'((X REAL) (V |3D|) => |3D|))))
(define-real-vector-space 3d)

コメントへの応答:

単一 のクラスが必要な場合real-vector-spaceは、本質的に、スロットの値に依存するタイプを持つスロットを要求しvector-addています。 これは、がそれを確認し、に適切な型を指定する必要があることを意味します。基本的に、これはタイプのすべてのオブジェクト が不変であるか、すべてのスロットが同時に変更されることを意味します。前者のオプションは、MOPを適切に使用することで実現できます。後者が Lisp で可能かどうかはわかりません。scalar-multV
(setf (underlying-set rvs) some-new-type)(add rvs)(s-mult rvs)some-new-typereal-vector-space

于 2017-01-09T15:52:47.870 に答える
2

Lisp Interface LibraryであるLILについて読むことができます。LIL : CLOS は高次に到達し、アイデンティティを脱ぎ捨て、Faré Rideau の変革的な経験を持っています。github ページに詳細があります。

基本的に、LIL は、動的スコープのおかげで暗黙的にできる追加のパラメーター (型クラスのようなインターフェース)を通じて、パラメトリック ポリモーフィズムを表現しようとします。

一方、表現したいことは OCaml モジュールで非常に簡単に実行できるので、必要に応じて、Rainer Joswig のアドバイスに従ってください (別の言語を使用してください)。

module type VectorSpace =
  functor (S : sig val dimension : int end)
          (F : sig type scalar val zero : scalar end) ->
  sig
    type vector = F.scalar array
    val add : vector -> vector -> vector
    val mul : F.scalar -> vector -> vector
  end

プロパティに関しては (コメントで要求されているように)、より複雑な型システム (Coq?) を使用する必要があるかもしれません。Common Lisp がうまく抽象化できる例として、Gábor MelisMGL-CUBEがあります。

于 2017-01-09T16:01:05.123 に答える