Haskell Language
タプル(ペア、トリプル、...)
サーチ…
備考
Haskellは、ネイティブに1つのコンポーネントを持つタプルをサポートしていません。
単位(written
()
)は、ゼロ要素を持つタプルとして理解できます。2つ以上のコンポーネントを持つタプルのコンポーネントを抽出するための事前定義された関数はありません。このような関数が必要と思われる場合は、タプル型ではなくレコードラベル付きのカスタムデータ型を使用することを検討してください。次に、レコードラベルを関数として使用してコンポーネントを抽出することができます。
タプル値を作成する
タプルを作成するには、カッコとカンマを使用します。 1つのコンマを使用してペアを作成します。
(1, 2)
より多くのコンポーネントを含むタプルを作成するには、より多くのカンマを使用します。
(1, 2, 3)
(1, 2, 3, 4)
タプルをunsugared形式で宣言することも可能です。
(,) 1 2 -- equivalent to (1,2)
(,,) 1 2 3 -- equivalent to (1,2,3)
タプルには異なるタイプの値を含めることができます。
("answer", 42, '?')
タプルは、リストやより多くのタプルなどの複雑な値を含むことができます。
([1, 2, 3], "hello", ('A', 65))
(1, (2, (3, 4), 5), 6)
タプル型の作成
タプル型を記述するには、かっことカンマを使用します。 1つのコンマを使用してペアの種類を記述します。
(Int, Int)
より多くのコンポーネントを含むタプル型を書くには、より多くのカンマを使用します。
(Int, Int, Int)
(Int, Int, Int, Int)
タプルには異なるタイプの値を含めることができます。
(String, Int, Char)
タプルは、リストやより多くのタプルなどの複雑な値を含むことができます。
([Int], String, (Char, Int))
(Int, (Int, (Int, Int), Int), Int)
タプルのパターンマッチ
タプルのパターンマッチングでは、タプルコンストラクタが使用されます。たとえば、ペアをマッチさせるには、 (,)
コンストラクタを使用します。
myFunction1 (a, b) = ...
より多くのコンポーネントとタプルをマッチさせるために、より多くのコンマを使用します。
myFunction2 (a, b, c) = ...
myFunction3 (a, b, c, d) = ...
タプルパターンには、リストパターンやより多くのタプルパターンなどの複雑なパターンを含めることができます。
myFunction4 ([a, b, c], d, e) = ...
myFunction5 (a, (b, (c, d), e), f) = ...
タプルコンポーネントを抽出する
使用fst
とsnd
(より機能をPrelude
またはData.Tuple
ペアの第一及び第二の成分を抽出します)。
fst (1, 2) -- evaluates to 1
snd (1, 2) -- evaluates to 2
または、パターンマッチングを使用します。
case (1, 2) of (result, _) => result -- evaluates to 1
case (1, 2) of (_, result) => result -- evaluates to 2
パターンマッチングは、2つ以上のコンポーネントを持つタプルに対しても機能します。
case (1, 2, 3) of (result, _, _) => result -- evaluates to 1
case (1, 2, 3) of (_, result, _) => result -- evaluates to 2
case (1, 2, 3) of (_, _, result) => result -- evaluates to 3
Haskellは、2つ以上のコンポーネントを持つタプルに対して、 fst
やsnd
ような標準関数を提供していません。 Hackageのtuple
ライブラリは、 Data.Tuple.Select
モジュールでこのような関数を提供します。
タプルにバイナリ関数を適用する(uncurrying)
uncurry
関数( Prelude
またはData.Tuple
から)を使用して、バイナリ関数をタプル上の関数に変換します。
uncurry (+) (1, 2) -- computes 3
uncurry map (negate, [1, 2, 3]) -- computes [-1, -2, -3]
uncurry uncurry ((+), (1, 2)) -- computes 3
map (uncurry (+)) [(1, 2), (3, 4), (5, 6)] -- computes [3, 7, 11]
uncurry (curry f) -- computes the same as f
2つの引数にタプル関数を適用する(カリングする)
タプルを2つの引数をとる関数に変換するには、 Prelude
またはData.Tuple
のcurry
関数を使用します。
curry fst 1 2 -- computes 1
curry snd 1 2 -- computes 2
curry (uncurry f) -- computes the same as f
import Data.Tuple (swap)
curry swap 1 2 -- computes (2, 1)
ペアコンポーネントの交換
swap
( Data.Tuple
から)を使用して、ペアのコンポーネントをスワップします。
import Data.Tuple (swap)
swap (1, 2) -- evaluates to (2, 1)
または、パターンマッチングを使用します。
case (1, 2) of (x, y) => (y, x) -- evaluates to (2, 1)
タプルの一致の厳密性
パターン(p1, p2)
は、最も外側のタプル・コンストラクタでは厳密であり、 予期しない厳密な動作につながる可能性があります 。たとえば、次の式は( Data.Function.fix
を使用して)分岐します。
fix $ \(x, y) -> (1, 2)
タプルコンストラクタで(x, y)
のマッチが厳密であるためです。ただし、 反駁不能なパターンを使用する次の式は、期待どおり(1, 2)
と評価されます。
fix $ \ ~(x, y) -> (1, 2)