44. 例ふたたび
sumA :: IArray a Int => …
→ 「 a が Int を要素に持つ変更不可配列」
という型制約をかけている
sumA :: … => a Int Int → Int
→ a Int Int → Int という型を持つので、
a として当てはまる(= IArray a Int というインス
タンスが宣言されている)もの全てに適用可能
45. 例ふたたび
Data.Array.IArray にインスタンスとして
IArray Array e
IArray UArray Int
が宣言されている。( e は型変数で、なんでもよい)
→ a が Array でも UArray でも型が合う!
IArray Array Int => Array Int Int → Int
OK !:インスタンス IArray Array e がある
IArray UArray Int => UArray Int Int → Int
OK !:インスタンス IArray UArray Int がある
46. 補足( 3 )
Q. かける制約は IArray a e でよかったのでは?
A. 実は、 IArray UArray e という要素の型 e につい
て一般化されたインスタンスはない。
(Data.Array.UArray のドキュメント参照)
→ なのでこの例では IArray a Int のインスタンス
宣言を使っており、そのため制約が IArray a Int
となっている。
IArray Array e => Array Int Int → Int
OK !:インスタンス IArray Array e がある
IArray UArray e => UArray Int Int → Int
NG !:インスタンス IArray UArray e はない
47. 補足( 4 )
本来、型制約に具体的な型を入れることはできな
い。
→ IArray a Int という制約はふつう許されない。
これを許可するのが FlexibleContexts 拡張