The Monomorphism Restriction
単相性制限
規則 1.
与えられた宣言グループが制限を受けないというのは以下の場合であり、その場 合にかぎる。
(a):
そのグループ内のすべての変数それぞれが関数束縛あるいは 単純パターン束縛により束縛されている。且つ
(b):
そのグループ内の単純パターン束縛により束縛されているすべての変数 それぞれには明示的な型シグネチャが与えられている。
通常の多相性に関する Hindley-Milner 制限は、その環境で束縛されて いない型変数のみが一般化できるというものである。これに、そのグルー プに対する一般化の段階では被制限宣言グループの被制約型変数は一 般化できない というのが加わる。(型変数が,いくつかの型クラス に属さなければならないというのが、制約を受けるということの意味で あることを思いだすこと。 4.5.2 節を見よ)。
規則 2.
http://www.sampou.org/haskell/report-revised-j/decls.html#sect4.5.5
あるモジュール全体に対する型推論が完了した時点で、まだ、単相型変 数であるものはすべて、曖昧であると考え、これは default の規則(4.3.4 節)を使って特 定の型に解決する。
単純パターン束縛とは,左辺が単一の変数である宣言のこと。
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