読者です 読者をやめる 読者になる 読者になる

by shigemk2

当面は技術的なことしか書かない

タプル

Haskell

タプルとは、複数の違う型の要素を格納して、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)]