(2008.8.18 新規作成。)
(2017.6.11 真偽値を加筆。)
Preludeモジュールを中心に、基本的な型と, 主に使いそうな関数をまとめてみました。
Haskellの基本型には、次のようのものがあります。
区分 | 型 | リテラル例 | 備考 |
---|---|---|---|
真偽型 | Bool | True, False | |
整数 | Int, Integer | 3 | |
実数 | Float, Double | 2.0 | |
有理数 | Rational | ● | |
文字 | Char | 'a' | |
文字列 | [Char], String | "abc" | |
リスト | ● | [1,2,3] | 値の型は同じでなければならない。 |
タプル | ● | ('a', 4) |
真または偽を表す真偽型は Bool
です。
Haskell では, Bool型は False
またはTrue
という値のみを持つ, 列挙型として定義されています.
data Bool = False | True deriving (Read, Show, Eq, Ord, Enum, Bounded)
したがい, 数値などからBool型への暗黙の変換はありません。True && 1
というコードはエラーになります。if
式で, Bool型でない値を条件式として書くこともできません。
真偽値に対して適用できる演算子は, &&
(論理and), ||
(論理or), そして not
です。否定の意味で !
は使えません。
Bool型は Enum
, Eq
などの型クラスのインスタンスになっています。
真偽値に, Eq
型クラスの==
, /=
も使えます。不一致が != ではなく, /=
なのに注意。
Enum
型クラスの関数も適用できます。succ False
は True, succ True
は例外発生。fromEnum True
が 1です。
Ord
型クラスの各演算子も使えます。enum値のとおり, True
のほうが大きいです。
Prelude> True && True True Prelude> False || True True Prelude> not True False
用語に注意:: ほかのプログラミング言語では,「型」=「クラス」となっているものが多いです。クラスをインスタンス化するとオブジェクトが生成されます。
いっぽうHaskell では, 型クラス (class) のインスタンスは「(データ) 型」(data type) です。クラスでは型に共通の関数などを定義できます。
Haskell のクラスは, ほかのプログラミング言語でいうモジュールや抽象クラスみたいなものです。
整数を表す型は Int と Integer です。Intは機械でプリミティブに表現できる大きさ (例えば31bit) までの整数, Integerはそれを超える大きさも扱えます (多倍長整数)。
Int型だと2の31乗でも値が壊れていますが, Integerにすると大丈夫です。
「リテラル::型名」とすると, リテラルを強制的に特定の型とできます。
Prelude> (2::Int) ^ 30 1073741824 Prelude> (2::Int) ^ 31 -2147483648 Prelude> (2::Int) ^ 32 0 Prelude> (2::Integer) ^ 32 4294967296
Int型は, 次のクラスのインスタンスになっています。
いっぽう Integer型は, 上のInt型のクラスのうち Boundedクラス以外のインスタンスになっています。
Bounded クラスは, 値の上限および下限を表す関数 maxBound, minBound を宣言しています。Integer型には上限および下限がありません。
Prelude> minBound::Int -2147483648 Prelude> maxBound::Int 2147483647
Haskellでは暗黙の型変換はしてくれないので, Int型の値とInteger型の値で計算するときは, 型を合わせないといけません。
Prelude> (2::Int) + (3::Integer) <interactive>:34:13: Couldn't match expected type `Int' with actual type `Integer' In the second argument of `(+)', namely `(3 :: Integer)' In the expression: (2 :: Int) + (3 :: Integer) In an equation for `it': it = (2 :: Int) + (3 :: Integer)
Int と Integer型の値は, toInteger
関数か fromIntegral
関数で揃えます。Intの範囲で十分か不明なときは, Int型のほうをInteger型に変換します。
次の例の前者は, Int型で表現できないのにInt型に変換しているため, 値が壊れています。エラーは出ません。
Prelude> (2::Int) + fromIntegral ((3::Integer) ^ 33) -1504003195 Prelude> fromIntegral (2::Int) + ((3::Integer) ^ 33) 5559060566555525
fromIntegral
関数は, Integralクラスのインスタンスである型 (= Int, Integer) の値を引数に取り, Numクラスのインスタンスの型へ変換します。
Numクラスについては後述。
fromIntegral :: (Integral a, Num b) => a -> b -- Defined in `GHC.Real'
四則演算も普通にできます。比較演算子もC言語スタイルです。演算子は優先順位があります。+, -より *, /が先。
比較では, 実数と整数を比較しても大丈夫。不等号は「!=」ではなく「/=」.
整数同士の除算は, 割り切れないときは実数になります。
Prelude> 2 + 1000 * 3 3002 Prelude> 1 == 1 True Prelude> 4 >= 3.99 True Prelude> 2 /= 3 True Prelude> 2 / 3 0.6666666666666666
(==), (/=) は Eqクラスで, (<), (<=), (>), (>=) は Ordクラスで宣言されています。
また, 「(演算子)」と書くと, 関数呼び出しスタイルで呼び出せます。
Prelude> (*) 2 50 100
Int, Integer型の共通のクラスである, Integralクラスについても見ておきましょう。
quotなど, 共通の関数が宣言されています。
class (Real a, Enum a) => Integral a where quot :: a -> a -> a rem :: a -> a -> a div :: a -> a -> a mod :: a -> a -> a quotRem :: a -> a -> (a, a) divMod :: a -> a -> (a, a) toInteger :: a -> Integer -- Defined in `GHC.Real'
Float型とDouble型があります。
両方とも, 次のクラスのインスタンスです。
有理数を表す Rational型もあります。まず, Data.Ratioモジュールを導入します。
Prelude> :module + Data.Ratio Prelude Data.Ratio> :info Rational type Rational = Ratio Integer -- Defined in `GHC.Real'
Rational型はRatio Integerの別名です。Ratioについて見てみましょう。
基本になる Num.
class Num a where (+) :: a -> a -> a (*) :: a -> a -> a (-) :: a -> a -> a negate :: a -> a abs :: a -> a signum :: a -> a fromInteger :: Integer -> a -- Defined in `GHC.Num' instance Num Integer -- Defined in `GHC.Num' instance Num Int -- Defined in `GHC.Num' instance Num Float -- Defined in `GHC.Float' instance Num Double -- Defined in `GHC.Float'
いろいろな型で使える演算子は、EqクラスやOrdクラスで定義されています。
3つ以上のタプルのときはどうやって取り出すの?