3

行き詰まったとき、私はちょうどhaskellを楽しみ始めていました。

クラスの新しいデータ型(これを呼びましょうMyType)を作成しようとしていますReadMytypeは型コンストラクターであるため、パラメーターとして別の型を取ります。このようなコードを書きたかった

    instance (Read a) => Read (MyType a) where
        readsPrec _ r = [foo (read r :: a ), r]

しかし、それは私に次のエラーを与えます

Could not deduce (Read a2) arising from a use of `read' from the context (Read a).

aReadableなので推測できると思ったのですが、どうやら間違っているようです。何か案は?

編集: 私は前のコードをに変更しました

readsPrec _ r = [foo (read r :: a ), ""]

だから私がタイプすると:read "myString" :: MyType aそれは完全にうまくいきます。read "myString"今、私は、コンテキスト内で使用する場合、読み取るタイプを指定する必要がないことを望んでいました。しかし、問題は

bar (read myString) a

ここで、 Ambiguos変数型bar:: MyType a -> a -> MyType aを取得し ました。

そのようなエラーを起こさずにそのようなことをすることは可能ですか?

コードを単純化しようとしていますが、重要なことを何も省略しなかったと思います。

4

1 に答える 1

6

次のように記述されている場合、コードは実際にタイプチェックします

instance(Read a)=> Read(MyType a)where
        readPrec _ r = [(foo(read r)、r)]

fooタイプがある場合a -> MyType areadsPrecコンパイラーは、の呼び出しがfooを返す必要があるという予想される型シグニチャーから理解できます。MyType aしたがって、(の型によってfoo)式read rは型を持つ必要がありaます。

しかし、それを注釈すると失敗するのはなぜ:: aですか?型変数はそれらが現れる型シグニチャーに対してローカルであるため、インスタンスの見出しaにはまったく関係がなく、実際には次のように言っています。式は任意の型を持つことができます。ただし、任意のタイプにはインスタンスがないため、エラーメッセージが表示されます。メッセージ内で、コンパイラは名前の衝突を避けるために内部の名前を変更しました。aread r :: aread rReadaa2

ただし、{-# LANGUAGE ScopedTypeVariables #-}モジュールヘッダーに追加すると、コードは期待どおりに機能します。これで、ainはインスタンスヘッダーread r :: aのタイプを参照し、すべてうまくいきます。a

readPrecを正しく使用していないことに注意してください。ただし、それは質問の一部ではないと思います。

于 2012-11-23T09:01:11.850 に答える