関数型プログラミングのデータ構造


11

私は現在LISP(特にSchemeとClojure)で遊んでいますが、関数型プログラミング言語で典型的なデータ構造がどのように扱われるのか疑問に思っています。

たとえば、グラフパス検索アルゴリズムを使用して問題を解決したいとします。そのグラフを関数型プログラミング言語(主にLISPに適用できる純粋な関数型に興味がある)で表現するにはどうすればよいでしょうか?グラフを完全に忘れて、他の方法で問題を解決できますか?

回答:


14

LISPで働いてからしばらく経ちましたが、覚えているように、基本的な非原子構造はリストです。他のすべてはそれに基づいています。したがって、各原子がノードである原子のリストがあり、その後にノードを他のノードに接続するエッジのリストがあります。他の方法もあると思います。

たぶんこのようなもの:

(
  (a (b c)),
  (b (a c)),
  (c (a b d)),
  (d (c))
)

次のようなグラフを作成できます。

a <-> b <-> c <-> d
^ ^
| |
+ --------- +

あなたが空想を得たいなら、あなたもそれに重みを加えることができます:

(
  (a (b 1.0 c 2.0)),
  (b (a 1.0 c 1.0)),
  (c (a 1.3 b 7.2 d 10.5)),
  (d (c -10.5))
)

また、これに興味があるかもしれません:CL-Graph(フレーズ「lisp graph structure」をgoogle-searchして見つけた)


4
これは少し遅れますが、「他のすべては[リスト]に基づいている」と誤解を招く可能性があることを警告する必要があります。Common Lisp、Scheme、Clojureはすべて、リストの上に構築されたものではなく、ベクトル、マップ、文字列、および構造/クラスを持っています。コード我々は、一般的にそれらを作成する書き込みは、リスト、例えば(メイクアレイ「(2 2):初期要素0)であるが、データ構造は、リストを使用して実装されていません。
コアダンプ

3

関数型言語は、非関数型言語と同じ方法でデータ構造を処理します。実装からインターフェイスを分離し、抽象データ型を作成します。

Lispで抽象データ型を作成できます。たとえば、グラフの場合、いくつかの関数が必要になる場合があります。

(define (get-vertices graph) ;; gets all the vertices from a graph
  ...)

(define (get-edges graph) ;; gets all the edges from a graph
  ...)

(define (get-weight vertex-from vertex-to) ;; get the weight of a specific vertex
  ...)

グラフへのインターフェイスを作成したら、実際のデータ構造をさまざまな方法で実装でき、プログラマーの効率、柔軟性、計算効率などの要因を最適化できます。

重要なのは、グラフを使用するコードがグラフインターフェイスのみを使用し、基になる実装にアクセスしないようにすることです。これにより、実際の実装から切り離されたクライアントコードがよりシンプルになります。


2

まあ、それはあなたのグラフが有向/無向、加重/無加重かどうかに依存しますが、有向、加重グラフ(最も一般的です)を表す1つの方法は、マップのマップを使用することです(Clojureで)

{
 :a {:b 3 :c 4} 
 :b {:a 1} 
 :c {}
}

は、ノード:a:bおよび:cを持つマップを表します。:aは、3の重みを持つ:bと4の重みを持つ:cを指します。:bは、1の重みを持つ:aを指します。:cは何も指しません。


1

Common Lispでは、ツリーを表す必要がある場合は、リスト(簡単なハックの場合)を使用するか、ツリークラスを定義します(または構造体ですが、クラスは一般的な関数とうまくやり取りします。 。

(defclass tree ()
  ((node :accessor node :initarg :node)
   (children :accessor children :initarg :children)))

コードにリテラルツリーが必要な場合は、必要なツリーmake-treeのリスト表現を取得し、それをツリーオブジェクトのツリーに変換する関数もおそらく定義するでしょう。


-2

Haskellでは、リストは基本的なデータ構造であり、より高度なデータ構造が必要な場合は、ツリーがnullまたはノードと2つのツリーのいずれかであるような再帰構造をよく使用します

data Tree a = Null | Node Tree a Tree  
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.