5

私は GHCi (バージョン 6.12.3) を使用して、Haskell で少し遊んでいます。<*>私は最近、ファンクターとアプリカティブ ファンクターについて読みました。アプリカティブ ファンクターに似たものをファンクターのプリミティブのみを使用して実装できないかどうかを考えました。少し考えた後fmap fmap、(ほぼ)理想的なタイプの

Functor f => f (a -> b) -> f (f a -> f b) またはより一般的に

(Functor f1, Functor f2) => f1 (a -> b) -> f1 (f2 a -> f2 b)

私は試した

let q = fmap fmap

次のエラーが発生しました

<interactive>:1:8:
    Ambiguous type variable `f1' in the constraint:
      `Functor f1' arising from a use of `fmap' at <interactive>:1:8-16
    Probable fix: add a type signature that fixes these type variable(s)

<interactive>:1:13:
    Ambiguous type variable `f' in the constraint:
      `Functor f' arising from a use of `fmap' at <interactive>:1:13-16
    Probable fix: add a type signature that fixes these type variable(s)

上記の型シグネチャを提案どおりに記述しても役に立ちませんでした。最もクレイジーなことは、入力したとき:t fmap fmapに上記と同等のタイプを取得したことです。

私は何を間違っていますか?GHCiが型を見つけたのになぜfmap fmap型エラーになるのですか?

4

2 に答える 2

7

モノモーフィズムの制限に遭遇しているようです。

GHCi で例を試すと-XNoMonomorphismRestriction、期待どおりの結果が得られます。

と書くことでこれを覆すこともできますlet f x = fmap fmap $ x。単相性の制限は、値に「似ている」トップレベルの定義にのみ適用されます。つまりf = something、明示的な引数を導入すると、それは適用されなくなります。これが最上位にない場合にも適用されません (たとえば、where条項内)。詳細については、リンクを参照してください。

于 2011-04-29T21:45:35.317 に答える
1

まだどこにもコメントできないので、回答を投稿します。前述のように、受け取っているエラーは単型性の制限によるものです。元の質問で指定された 2 つのうちのいずれかに型シグネチャを修正すると、実際に ghci が期待どおりに幸せになります。構文が少し間違っているだけかもしれません。

Prelude> let q :: (Functor f) => f (a -> b) -> f (fa -> fb); q = fmap fmap
前奏曲> :tq
q :: (ファンクタ f) => f (a -> b) -> f (fa -> fb)

Prelude> let q :: (Functor f1, Functor f2) => f1 (a -> b) -> f1 (f2 a -> f2 b); q = fmap fmap
前奏曲> :tq
q :: (ファンクター f1, ファンクター f2) => f1 (a -> b) -> f1 (f2 a -> f2 b)
于 2011-04-30T11:48:31.207 に答える