タプルとは、複数の違う型の要素を格納して、1つの値にするために使う。
リストとの違いは、
| リスト | タプル |
| 型は同じ | 違う型を格納できる |
| サイズを変えられる | サイズは固定 |
といったところでしょうか。
# タプルの基本
Main> (1, 3)
(1,3)
# 違う型の値もタプルなら格納できる
Main> (3, 'a', "hello")
(3,'a',"hello")
Main> (50, 50.4, "hello", 'b')
(50,50.4,"hello",'b')
# サイズの違うタプルをリストにすることは出来ない。なぜなら、サイズの違うタプルは別の型として見做されるから。
Main> [(1,2),(8,11,5),(4,5)]
<interactive>:109:8:
Couldn't match expected type `(t0, t1)'
with actual type `(t2, t3, t4)'
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)]
# 同じサイズのタプルはリストにすることが出来る
Main> [(1,2),(8,11)]
[(1,2),(8,11)]
# タプルの最初の要素を取得する(ペア限定。トリプルには使えない)
Main> fst (8,11)
8
Main> fst ("Wow", False)
"Wow"
# タプルの2番目の要素を取得する(ペア限定。トリプルには使えない)
Main> snd (8,11)
11
Main> snd ("Wow", False)
False
# zip でペアのリストを作る
Main> zip [1,2,3,4,5] [5,5,5,5,5]
[(1,5),(2,5),(3,5),(4,5),(5,5)]
Main> zip [1..5] ["one", "two", "three", "four", "five"]
[(1,"one"),(2,"two"),(3,"three"),(4,"four"),(5,"five")]
# 長いほうのリストは必要なぶんだけ使われ、余りは無視される
Main> zip [5,3,2,6,2,7,2,5,4,6,6] ["im", "a", "turtle"]
[(5,"im"),(3,"a"),(2,"turtle")]
# Haskellは遅延評価なので、有限リストと無限リストをzipすることが出来る
Main> zip [1..] ["apple", "orange", "cherry", "mango"]
[(1,"apple"),(2,"orange"),(3,"cherry"),(4,"mango")]
# 条件に適った直角三角形の長さを求めてみる
# 条件1 3辺の長さは全て整数
# 条件2 各辺の長さは10以下
# 条件3 周囲の長さは24に等しい
# まず、条件2を見たすa b cのトリプルのリストを出力する(ただしこの組み合わせは10^3で1000通りある)
Main> let triples = [ (a,b,c) | c <- [1..10], a <- [1..10], b <- [1..10] ]
# ナントカの定理 a^2 + b^2 = c^2 に適った a b c のトリプルのリストを出力
# cが斜辺なので、一番長い
Main> let rightTriangles = [ (a,b,c) | c <- [1..10], a <- [1..c], b <- [1..a], a^2 + b^2 == c^2 ]
Main> rightTriangles
[(4,3,5),(8,6,10)]
# 3つの条件を満たすリストを出力
Main> let rightTriangles = [ (a,b,c) | c <- [1..10], a <- [1..c], b <- [1..a], a^2 + b^2 == c^2, a+b+c == 24 ]
Main> rightTriangles
[(8,6,10)]