前回は良く理解してないところを見てしまったので、分かりそうなところに絞ろう。
*Test> :t h
h :: (Num a) => a -> a -> a
今回はこれを理解することが目的。
あ、ちょっと前回と違うね。
:t、:typeを使って情報を表示してみた。
これは型を調べるときに使うんだ。
さて、まずaだ。何でも入る型らしい。ちゃんというと、多相型。
どんな型の値が入っても気にしない。
でも、h x y = x + yの通り、加算が出来る値が入らないといけない。
それを規定するのが(Num a) => aの部分。
Num⊃aと書くと分かりやすいかな。aはNumの特性を持っていなくちゃいけない。
これを型クラスというんだ(これをスーパークラスっていうのかと思っていたけど)。
では、Numを調べてみよう。
*Test> :i Num
class (Eq a, Show a) => Num a where
(+) :: a -> a -> a
(*) :: a -> a -> a
(-) :: a -> a -> a
negate :: a -> a
abs :: a -> a
signum :: a -> a
fromInteger :: Integer -> a
-- Imported from GHC.Num
instance Num Float -- Imported from GHC.Float
instance Num Double -- Imported from GHC.Float
instance Num Integer -- Imported from GHC.Num
instance Num Int -- Imported from GHC.Num
ここにも=>が使われている。左側は(Eq a, Show a)だね。
これもクラスが型を制約するのと同様に解釈できる。
Num aはEq aやShow aに含まれるクラスなんだ。この左側の方をスーパークラスというみたい。
右側のクラスもスーパークラスに適用できる関数が適用できなくてはいけない。
これは後回しにして、ここに書かれていることを先に見よう。
その下は何となく分かるね。Numは四則演算が出来る。
f xの形の関数にnegate,abs,signum,fromIntegerがある。
fromIntegerはIntegerからより一般的な型に変更する関数みたいだ。
他の関数は試してみないと分からないかな。
*Test> negate 10
-10
*Test> abs 100
100
*Test> abs (negate 10)
10
*Test> signum 10
1
*Test> signum (negate 10)
-1
NumのインスタンスにはFloat,Double,Integer,Intがあるって書いてある。
では、ここで明示的な型宣言を試してみよう。
*Test> 1::Float
1.0
::で型を示すと、その型になる。もちろん、どんな型でも良い訳ではない。
*Test> :t 1
1 :: (Num t) => t
これを見ると、1はNumに含まれる型であるということだ。色々試してみる。
*Test> :t 1::Float
1::Float :: Float
*Test> :t 1::Int
1::Int :: Int
*Test> :t 1::Hoge
<interactive>:1:3: Not in scope: type constructor or class `Hoge'
*Test> :t 1::String
<interactive>:1:0:
No instance for (Num String)
arising from the literal `1' at <interactive>:1:0
Probable fix: add an instance declaration for (Num String)
In the expression: 1 :: String
Numに含まれる型には問題なく変換できる。
Hoge型はないからエラーが出る。型構築子かクラスであるHogeが必要だって。
String型はNumのインスタンスではないから、これもエラー。Num Stringを宣言すれば出来るかも知れない。
出来るかどうかは良く分からないけど……。
そしてもう一つ。
*Test> :t 1::Num
<interactive>:1:3:
Class `Num' used as a type
In an expression type signature: Num
In the expression: 1 :: Num
これは失敗。Numはクラスであって、型ではない。だから、型宣言(直訳で型解析の表現か)でNumは使えないって。
クラスは型ではないんだね。
クラスと型ついて分かったかな?
スーパークラスについて……長くなったからまた次の機会に、ね。
順番に考えた方が分かりやすいだろうけど、気になるところから調べてみようね。
ちょっと
テキストアドベンチャーぽい。
最終更新:2007年09月26日 17:55