9

Haskell98 で抽象化を試みていますが、その方法がわかりません。

私がやりたいことは、リストに変換できる型のクラスを定義することです。

toList :: a -> [b]

しかし、このメソッドのクラスを定義する方法がわかりません。以下の3つの案を出しました。

class ToList a b where
    toList :: a -> [b]

class ToList a where
    toList :: a -> [b]

class ToList a where
    toList :: a b -> [b]

Haskell98 では複数のパラメーター クラスが許可されていないため、最初のものは機能しません。

b は a に依存しており、すべての b に対して実装できないため、2 番目の方法は機能しません。

「b」が最後の型パラメーターではない型でクラスをインスタンス化する方法がわからないため、3番目も機能しません。

data HTree a b = Nil | Node a b (HTree a b) (HTree a b)

toList Nil = []
toList Node x y l r = toList l ++ [(x,y)] ++ toList r

また

toList Nil = []
toList Node x y l r = toList l ++ [x] ++ toList r

どうすればそのようなことをするでしょうか?

4

3 に答える 3

9

任意のインスタンス に関数を提供する標準ライブラリのData.Foldableも参照してください。インスタンス化するには少し洗練された作業が必要ですが、良い習慣になります。おまけとして、あなたの型はドキュメントの例のインスタンスとほぼ同じです。toListFoldableFoldableHTree

さらに、次のように変更することをお勧めしますHTree

data HTree a = Nil | Node a (HTree a) (HTree a)

そして、HTree (a,b)の代わりに使用しHTree a bます。この単一パラメーターのバージョンは、標準の型とインスタンスを使用してより簡単に構成でき、両方のパラメーターに同じように依存するため、何が起こっているのかがより明確になります。これは であり、Functorそのようなインスタンスを定義すると、この型が非常に使いやすくなります。

于 2008-11-23T07:11:24.067 に答える
4

Type クラスは最初に思われるほど有用ではないことをお勧めします。推定クラスにインターフェイス メソッドが 1 つしかない場合は、代わりに関数型を宣言することを検討してください。私もオブジェクト指向のバックグラウンドを持っており、実際には「データ」を使用するべきだったのに、「クラス」を自分が思っていた意味にしようと多くの時間を費やしていたことに気付きました。

toList 関数を記述し、それを「リフト」してデータ構造を操作する方がはるかに簡単です。実際、高く評価されている「Yet Another Haskell Tutorial 」では、その方法を示す大規模な演習が行われ、例としてバイナリ ツリーが使用されています。リフトを実行することの優れた点は、重要なもの (toList の実装ではなく、データ型の構造) を区別することです。そのため、リフトが実行されて「データ型の順序でトラバーサル」が実行されると、リフトを使用して次のことができます。何でもします - toList、print、何でも。toList のサポートはデータ構造の重要な部分ではないため、クラス宣言に含める必要はありません。重要な部分は、データ構造をどのようにトラバースするかです。

于 2008-11-21T21:10:37.557 に答える
-1

クラス ToList の最後のオプションを選択し、(HTree a)ToList のインスタンスを作成することをお勧めします。次に、たとえばではなく、toListタイプ があります。a を「キー」型、b を「値」型と考えていると思います。(HTree a b) -> [b](HTree a b) -> [(a,b)]

class ToList a where
    toList :: a b -> [b]

data HTree a b = Nil | Node a b (HTree a b) (HTree a b)

instance ToList (HTree a) where
    toList Nil = []
    toList (Node x y l r) = toList l ++ [y] ++ toList r

test = toList (Node "a" 1 (Node "b" 2 Nil Nil) Nil)
-- test == [2,1]
于 2008-11-22T11:27:18.920 に答える