The Monomorphism Restriction

単相性制限


規則 1.
与えられた宣言グループが制限を受けないというのは以下の場合であり、その場 合にかぎる。


(a):
そのグループ内のすべての変数それぞれが関数束縛あるいは 単純パターン束縛により束縛されている。且つ


(b):
そのグループ内の単純パターン束縛により束縛されているすべての変数 それぞれには明示的な型シグネチャが与えられている。


通常の多相性に関する Hindley-Milner 制限は、その環境で束縛されて いない型変数のみが一般化できるというものである。これに、そのグルー プに対する一般化の段階では被制限宣言グループの被制約型変数は一 般化できない というのが加わる。(型変数が,いくつかの型クラス に属さなければならないというのが、制約を受けるということの意味で あることを思いだすこと。 4.5.2 節を見よ)。


規則 2.
あるモジュール全体に対する型推論が完了した時点で、まだ、単相型変 数であるものはすべて、曖昧であると考え、これは default の規則(4.3.4 節)を使って特 定の型に解決する。

http://www.sampou.org/haskell/report-revised-j/decls.html#sect4.5.5

単純パターン束縛とは,左辺が単一の変数である宣言のこと。

x = 10 -- 単純パターン束縛
f x y = x + y -- 関数束縛
f = \x y -> x + y -- 単純パターン束縛
y | x < 0  = "Negative" -- パターン束縛
  | x == 0 = "Zero"
  | x > 0  = "Positive"
Prelude> let f x y = x + y
Prelude> :t f
f :: (Num a) => a -> a -> a
Prelude> let g = \x y -> x + y
Prelude> :t g
g :: Integer -> Integer -> Integer

gは単純パターン束縛であり,明示的な型シグネチャがないため単相性制限を受ける。さらに(Num a)という制約があるため,一般化されない。gの型はdefault規則によって決まった結果,だと思う。fと同じ型にするためには明示的に型を書く必要がある。

Prelude> let {g :: (Num a) => a -> a -> a; g = \x y -> x + y}
Prelude> :t g
g :: (Num a) => a -> a -> a