それは任意ではありません。 Hindley-Milner型の推論は、より高級な型とカルト型のコンストラクタアプリケーションで動作する方法です。型変数の統一は、生成型コンストラクタの概念に基づいています。つまり、(f a) ~ (g b)
の場合は、f ~ g
とa ~ b
です。ここで、~
は型の平等です。
(fmap f someT)
のような式の統一に、someT :: T a b
を適用しましょう。私はsomeT
以外のすべての型変数を与えることから始めて、統一の仕方を操作します。 fmap
は、最初の引数としてf
提供されているという事実によって
someT :: T a b
fmap :: (c -> d) -> f c -> f d
f :: e
、我々は(c -> d) ~ e
を統一。だから..
fmap f :: f c -> f d
someT :: T a b
これはここに世代が入るところです。ここからは、(f c) ~ (T a b)
と表示されます。わかりやすくするために括弧を追加してみましょう:(f c) ~ ((T a) b)
これは、型コンストラクタがHaskellでどのように動作するかです。これらは、term-level関数と同じ方法でカリー化されています。一般的には、f ~ (T a)
とc ~ b
です。それから、次に
:
fmap f someT :: T a d
だから、Functor
インスタンスタイプT
の第二の型引数にのみ動作しなければならないことを必ずしも事実です。
もちろん、これはすべて型推論アルゴリズムに戻ります。ヒンドレーミルナーやカレータイプのコンストラクタをあきらめて、物事を違うものにすることができます。しかし、結果はハスケルとはまったく異なるでしょう。
'Flip f a b = f b a'と' TypeSynonymInstances'で取り除くことができるかもしれませんが、実際には引数の順序を変更するか、代わりにnewtypeを使うべきです。 – Lazersmoke
@Lazersmoke:型同義語を完全に適用する必要があるので、これはうまくいかないでしょう。 –
私はそれが直接質問に答えることはできませんが、おそらくそれをBifunctorにして、aまたはbまたはその両方にマップできることを知っていますか? – ppb