Elmのタプルは、2つまたは3つの値を保持でき、それぞれの値はどのような型でもかまいません。 Elmでは、タプルは主に単純な一時的な型に使われます。 そのため、タプルが持てる値は最大3つまでで、さらに後押しするかのように、用意されている便利な関数も2つの値のものだけです。 より複雑なデータには、レコードに切り替えるのが一番です。
type alias IntStringTuple = (Int, String)
aTuple : IntStringTuple
aTuple = (123, "elements can be of differing types")
anotherTuple : (String, String)
anotherTuple = Tuple.pair "this time it's" "two strings"
--> ("this time it's", "two strings")
Tuple.first aTuple
--> 123
Tuple.second aTuple
--> "elements can be of differing types"
タプルは、タプルパターンマッチを使って束縛の中で_分解_できます。
分解は、let式、関数宣言、case式の中で行えます。
repeatString : (Int, String) -> Bool
repeatString aTuple =
let
(aNumber, aString) = aTuple
in
String.repeat aNumber aString
repeatStringAgain : (Int, String) -> Bool
repeatStringAgain (aNumber, aString) = String.repeat aNumber aString
has123 : (Int, String, Bool) -> Bool
has123 aTuple =
case aTuple of
(123, _, _) ->
True
(_, "123", _) ->
True
(_, _, True) ->
True
_ ->
False
AazraとRuiは、海賊をテーマにした宝探しを考えています。地図上の場所が付いた宝物の配列と、同じく地図上の場所が付いた場所名の配列があります。
| 宝物 | 位置 |
|---|---|
| Amethyst Octopus | (1, F) |
| Angry Monkey Figurine | (5, B) |
| Antique Glass Fishnet Float | (3, D) |
| Brass Spyglass | (4, B) |
| Carved Wooden Elephant | (8, C) |
| Crystal Crab | (6, A) |
| Glass Starfish | (6, D) |
| Model Ship in Large Bottle | (8, A) |
| Pirate Flag | (7, F) |
| Robot Parrot | (1, C) |
| Scrimshaw Whale's Tooth | (1, F) |
| Silver Seahorse | (4, E) |
| Vintage Pirate Hat | (7, E) |
| 場所の名前 | 位置 | 区域 |
|---|---|---|
| Seaside Cottages | (C, 1) | Blue |
| Aqua Lagoon (Island of Mystery) | (F, 1) | Yellow |
| Deserted Docks | (A, 2) | Blue |
| Spiky Rocks | (D, 3) | Yellow |
| Abandoned Lighthouse | (B, 4) | Blue |
| Hidden Spring (Island of Mystery) | (E, 4) | Yellow |
| Stormy Breakwater | (B, 5) | Purple |
| Old Schooner | (A, 6) | Purple |
| Tangled Seaweed Patch | (D, 6) | Orange |
| Quiet Inlet (Island of Mystery) | (E, 7) | Orange |
| Windswept Hilltop (Island of Mystery) | (F, 7) | Orange |
| Harbor Managers Office | (A, 8) | Purple |
| Foggy Seacave | (C, 8) | Purple |
プレイヤーは地図の中を巡りながら、宝を拾い集めていきます。 宝物と場所では位置の書き方をわざと変えてあり、そこがまた難しくなっています。 さらに、特別な場所もいくつかあります。そうした場所では、特定の宝物を別の宝物と交換でき、ゲームにひと味違った面白さを加えています。 このゲームを手伝う関数を書くのが、この演習の目的です。
Place Location(('C', 1)など)を受け取り、Treasure Location((1, 'C')など)に変換するplaceLocationToTreasureLocation関数を実装しましょう。
placeLocationToTreasureLocation ('C', 1)
--> (1,'C')
PlaceLocation(('C', 1)など)を受け取り、TreasureLocation((1, 'C')など)と一致する場合にtrueを返すtreasureLocationMatchesPlaceLocation関数を実装しましょう。
treasureLocationMatchesPlaceLocation ('C', 1) (1, 'C')
--> true
treasureLocationMatchesPlaceLocation ('C', 1) (2, 'C')
--> false
Place(("Aqua Lagoon (Island of Mystery)", ('F', 1))など)と宝物の配列を受け取り、そこに見つけられる宝物の数を返すcountPlaceTreasures関数を実装しましょう。
place = ("Aqua Lagoon (Island of Mystery)", ('F', 1))
countPlaceTreasures place treasures =
--> 2
Treasure(("Amethyst Octopus", (1, 'F'))など)とPlace(("Seaside Cottages ", ('C', 1))など)を受け取り、次の組み合わせに対してtrueを返すspecialCaseSwapPossible関数を実装しましょう。
この関数は、if文ではなく、アドホックなタプルを使ったcase式として実装してみましょう(これはElmでよく使われる書き方です)。