3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

すごいH本読んだからまとめ 3 「型」

Posted at

はじめに

Haskellの型

型を確認してみる

  • ghciに:tと打ち込むと型を表示できる
*Main Lib> :t 'a' -- シングルクォーテーション、1文字
'a' :: Char
*Main Lib> :t 'ab' -- シングルクォーテーション、複数文字
<interactive>:1:1: error:
    ? Syntax error on 'ab'
      Perhaps you intended to use TemplateHaskell or TemplateHaskellQuotes
    ? In the Template Haskell quotation 'ab'
*Main Lib> :t "aiueo" -- ダブルクォーテーション、複数文字
"aiueo" :: [Char]
*Main Lib> :t True -- 真偽値
True :: Bool
  • 値に対する型の表示は「値 :: 型」というフォーマットで出力される。

関数の型

  • Haskellは関数の型を明示的に宣言することができる。
isZero :: Int -> Bool -- 引数 -> 戻り値
isZero x = x == 0 -- Int型のxを受け取ってそれが0より大きいかどうかをBool型で返す。
*Main> isZero 9
False

-- 引数が複数ある場合は
-- 「引数 -> 引数 -> ...-> 戻り値」の順に型を定義する。
addThree :: Int -> Int -> Int -> Int  
addThree x y z = x + y + z  

型の種類

説明
Int 整数
Integer 巨大な整数
Float 浮動小数点数
Double 倍精度浮動小数点数(Floatの2倍のbit数で少数を表すので精度高まる)
Bool TrueとFalseの2つを表す
Char Unicode文字
タプル ()の中の要素数と要素の型に依存して型が決まる。空のタプルも()の型を持つ
  • Haskellにおける文字列は文字のリストとして考えることができる
*Main Lib> ['a','i','u','e','o'] == "aiueo" -- 左右は同じもの
True

型変数

  • takeの型を確認するとリストの中身にaと入っている。
*Main> :t take
take :: Int -> [a] -> [a]
*Main> take 3 "aiueo" -- 文字列は文字のリスト
"aiu"
  • takeは指定された数の分だけ、リストの先頭を取り出す関数。
*Main> take 2 [1,2,3]
[1,2]
  • リストの中身はどんな型でも気にしない。そのため、aと表記することで、「どんな型でもいいですよ」を表す。
  • aのようなものを型変数と呼ぶ
  • 型変数を用いた関数は多相的関数と呼ぶ

型クラス

型クラスとは

  • あるに特定の関数を適用したときの振る舞いを定義するもの
  • 型と型クラスは多体多の関係
  • 文章ではなんだかよくわからないので具体例を確認する。

例(等値性)

  • (==)関数の型を確認してみる。(* (==)という書き方についてはこちら)
ghci> :t (==) 
(==) ::(Eq a) => a -> a -> Bool
  • いままで見たことない=>という書き方とその左側にある(Eq a)なるもの。ここが型クラス。
  • =>より右は同じ型の値を2つ突っ込んだら真偽値が入るという関数の型(私達は既に知っているはず。)
(Eq a) => a -> a -> Bool
  • (Eq a) は「Eqにおいて性質が保証された型a」というふうに読める。
  • A => B は「AならばがB成立する。」と考えて大丈夫そうなので
  • (Eq a) => 左辺で「Eqという性質を満たす型aならば左辺が成立」と読める。
  • aが型変数ということはIntやリストなど、様々な型についてEqによる等値性の定義がされていると考えられる。

具体的に値を入れて関数を実行してみると

*Main> (==) [1,2,3] [1,2,3]
True
*Main> (==) [1,2,3] [1,2,2] -- 要素数が同じだけではFalse
False
  • 要素数が一緒なだけでなく、要素のパターンまで同じでないと(==)関数の結果がTrueにならないのは、Eqがリストの等値性をそういう定義にしているからなのである。
  • 型クラスはこういう風に「あるに特定の関数を適用したときの振る舞いを定義」する

他の型クラス

  • Show

文字列として表現できるもの

*Main> :t show --show関数の定義をみると
show :: Show a => a -> String -- Show型クラスを条件にした定義が書いてある。
-- 関数名と型クラス名が同じで分かり辛いが大文字から始まるShowは「文字列として表現できる」ということを表す型クラス。
-- showは「与えられた型を文字列にする」関数
*Main> show 1
"1"
*Main> show 3.0
"3.0"
*Main> show 'a'
"'a'"
*Main> show "aaa"
"\"aaa\""
*Main> show True
"True"
*Main> show False
"False"
*Main> show [1,2,3,4]
"[1,2,3,4]"
  • Num

数のように振る舞えるもの

*Main> :t (+) -- 足し算の型確認
(+) :: Num a => a -> a -> a -- 数のように振る舞えるならなんでも足し算していい
*Main> (+) 20 30 --整数でも
50
*Main> (+) 20.0 30.0 -- 浮動小数点数でもね
50.0

他にも

  • Ord(順番がある)
  • Enum(列挙可能)
  • Bounded(上限と下限をもつ)
  • Floating(浮動少数点数のみ)
  • Integral(実数のみ)

とかの型クラスで型の性質を定義できる。(基本的な型クラスの定義はHaskellがやっといてくれる)

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?