1

隣接行列に基づいたグラフの独自の実装を作成し、Readクラスのインスタンスを作成しました。

私のグラフは、エッジのタイプとなるタイプを入力として受け取ります。

こんな表現をしてみたら

read " - - 8 \n - 9 - \n 1 2 3" :: GraphADJ Int

これは問題なく機能します(3つのノードと、最初のノードから3番目のノード、2番目のノードから2番目のノード、3番目のノードからすべてのノードのエッジを持つグラフです)。

私がやりたかったのは、型推論にエッジのタイプを伝えるのではなく、それらをコンテキストに入れることです(のようにread"4"+3)。

insertEdgeグラフ、いくつかのノード、新しいエッジを取得する関数があります。

insertEdge :: Graph g n e => g -> (n, n) -> e -> g

(のインスタンスとGraphなるグラフの一般的なクラスです)GraphADJ

だから私がやろうとすると

 insertEdge (read " - - 8 \n - 9 - \n 1 2 3" :: GraphADJ Int) (1,2) 3

正常に動作しますが、型を明示的にしないと、エラーが発生します Ambiguous type variables

何かを忘れたのですか、Readそれとも何かが足りないのですか?

4

1 に答える 1

3

問題は、コンパイラが読み取り用の型を推測するのに十分な情報を持っていないことです。

ntoIntおよびetoコンパイラの型情報を指定してIntも、の情報はありませんg。それが知っているgのは、のインスタンスを持つタイプですGraph g Int Intgそのようなインスタンスに生息する単一のタイプがあっても、それはまだ推測できません。

コンパイラは、現在のスコープに、そのような動作を許可するとモジュールをインポートすることによってコードが破損する可能性があるようなインスタンスを持つタイプのみが存在することを自動的に認識できません。

したがって、解決策は、明示的な署名を提供するか、にinsertEdge十分な情報を提供するために明示的な具象型を提供する特殊なバージョンを作成することですread。後者は、同じタイプで複数の場所で使用している場合に役立ちます。

于 2013-01-23T18:10:04.890 に答える