Tuples

tupleはlistと似ているが、複数の値を一つの値に保持する

In [1]:
(1, 2)
(1, "Hello")
(1,2)
(1,"Hello")
  • tupleはどれくらい要素があるべきで、それぞれの要素の型がどうあるべきかわかっているときに使う
  • tupleは異なった型の要素をもつことができる
In [2]:
[(1, 2), (8, 11, 5), (4, 5)]
<interactive>:1:10: error:
• Couldn't match expected type ‘(a, b)’ with actual type ‘(Integer, Integer, Integer)’
• In the expression: (8, 11, 5)
In the expression: [(1, 2), (8, 11, 5), (4, 5)]
In an equation for ‘it’: it = [(1, 2), (8, 11, 5), (4, 5)]
• Relevant bindings include it :: [(a, b)] (bound at <interactive>:1:1)
In [3]:
[(1, 2), ("One", 2)]
<interactive>:1:3: error:
• Could not deduce (Num String) arising from the literal ‘1’
from the context: Num b bound by the inferred type of it :: Num b => [(String, b)] at <interactive>:1:1-20
• In the expression: 1
In the expression: (1, 2)
In the expression: [(1, 2), ("One", 2)]

tupleが入ったlistを作るとき、以下の場合にエラーがおきる

  • tupleの要素数が異なる
  • 要素数が同じでもtupleの型の組み合わせが異なる
In [4]:
[("Christopher", "Walken", 55), ("Tom", "York", 50)]
[("Christopher","Walken",55),("Tom","York",50)]
  • tpuleは様々なデータを表現するためにも使用できる。
  • 例えば上記は、人物の情報(First name, Last name, age)をtupleで表現している
In [5]:
(1)
:t (1)
Redundant bracket
Found:
(1)
Why Not:
1
1
(1) :: forall p. Num p => p
  • 要素が1個のtupleは作ることができない。
  • 要素の値そのものと同等であり、tupleにする価値がないため

tupleに関する関数

ペア(2要素のみ)のtupleでしか使えない関数

In [6]:
fst (8, 11)
fst ("Wow", False)
8
"Wow"
  • fst
    • 1個目の要素を返す
In [7]:
snd (8, 11)
snd ("Wow", False)
Evaluate
Found:
snd ("Wow", False)
Why Not:
False
11
False
  • snd
    • 2個目の要素を返す

zip

In [8]:
zip [1,2,3,4,5] [5,5,5,5,5]
[(1,5),(2,5),(3,5),(4,5),(5,5)]
In [9]:
zip [1 .. 5] ["one", "two", "three", "four", "five"]
[(1,"one"),(2,"two"),(3,"three"),(4,"four"),(5,"five")]
  • 2つのlistからindexが同じ要素のペアのtuple listを返す。
In [10]:
zip [5,3,2,6,2,7,2,5,4,6,6] ["im","a","turtle"]
[(5,"im"),(3,"a"),(2,"turtle")]
  • 要素数が異なる場合、要素数が少ないlistに長さが合わせられる
In [11]:
zip [1..] ["apple", "orange", "cherry", "mango"]
[(1,"apple"),(2,"orange"),(3,"cherry"),(4,"mango")]
  • 要素数が少ない方に合わせられるので、無限リストとも組み合わせられる

リスト内包表記でtupleのリストを作成する

  • 全ての辺の大きさが10以下で、全周の大きさが24の直角三角形のリストを求めたい
In [12]:
let triangles = [ (a,b,c) | c <- [1..10], b <- [1..10], a <- [1..10] ]
  • 最初に各辺が10以下の三角形の組み合わせを全て生成するリスト内包表記を書いてみる
In [13]:
let rightTriangles = [ (a,b,c) | c <- [1..10], b <- [1..c], a <- [1..b], a^2 + b^2 == c^2]    
rightTriangles
[(3,4,5),(6,8,10)]

続いて、3平方の定理を使って直角三角形として成立する組み合わせのみ抽出するフィルターを追加する

In [14]:
let rightTriangles' = [ (a,b,c) | c <- [1..10], b <- [1..c], a <- [1..b], a^2 + b^2 == c^2, a+b+c == 24] 
rightTriangles'
[(6,8,10)]

最後に、辺の合計が24である組み合わせのみ抽出するフィルターを追加する

  • 関数型プログラミング言語では、ある一つの集合からはじめて、それから変形やt輸出を追加して問題を解決することは一般的なパターンである

3. Types and Typeclsses

  • Haskellは静的型付けシステムを持っており、コンパイル時に全ての式の型を知っているため、コードをより安全にすることができる
    • 実行時にクラッシュする代わりにコンパイル時にエラーを検知できる
  • JavaやPascalと違いHaskellには型推論を持っている
  • 型(Type)とは全ての式が持っているラベルのようなもの
In [15]:
:t 'a'
:t True
:t "Hello!"
:t (True, 'a')
:t 4 == 5
'a' :: Char
True :: Bool
"Hello!" :: [Char]
(True, 'a') :: (Bool, Char)
4 == 5 :: Bool
  • GHCIでは:tコマンドで式の型を知ることができる
    • :tコマンドに渡した式 ::型」 の形式で表示される
    • 明示的な型名は先頭文字が大文字

関数の型

  • 関数を書く時、型定義を明示的に与えることもできる
In [16]:
removeNonUppercase :: [Char] -> [Char]
removeNonUppercase st = [ c | c <- st, c `elem` ['A'..'Z']]
  • [Char]はStringという型シノニムを持っているため以下のようにも定義できる
In [17]:
removeNonUppercase :: [Char] -> [Char]
removeNonUppercase st = [ c | c <- st, c `elem` ['A'..'Z']]
In [18]:
addThree :: Int -> Int -> Int -> Int  
addThree x y z = x + y + z
In [19]:
addThree 1 2 3
6
  • 関数が複数の引数を取る場合は->で区切って書く
    • 引数と戻り値の型には区別はなく、最後の型が戻り値の型になる
In [20]:
plus :: Int -> Int -> Int
plus x y = x + y
:t plus

addOne = plus 1
:t addOne
plus :: Int -> Int -> Int
addOne :: Int -> Int
In [21]:
addOne 2
3

代表的な型の概要

  • Int
    • 整数
    • 値の範囲(最小値と最大値)を持つ
In [22]:
factorial :: Integer -> Integer  
factorial n = product [1..n]
In [23]:
factorial 50
30414093201713378043612608166064768844377641568960512000000000000
  • Integer
    • 整数
    • 制限範囲を持たず巨大な整数を扱うことができる
In [24]:
circumference :: Float -> Float  
circumference r = 2 * pi * r
In [25]:
circumference 4.0
25.132742
  • Float
    • 単精度浮動小数点数
In [26]:
circumference' :: Double -> Double  
circumference' r = 2 * pi * r
In [27]:
circumference' 4.0
25.132741228718345
  • Double
    • 倍精度浮動小数点数
  • Bool
    • Bool型。TrueとFalse
  • Char
    • 文字
In [28]:
()
:t ()
()
() :: ()

空のtupleは一個の値のみ持つ

In [ ]: