宝箱

宝箱

学習演習

はじめに

ジェネリクス

はじめに

ジェネリクスは、コードの再利用を可能にする言語の機能です。 たとえば、配列の長さを計算するのに、その配列がどんな型を持つかは関係ないはずです。 だからこそ、length関数は型シグネチャの中でジェネリックな型パラメーターaを使っています。

length : List a -> Int

型のパラメーター

ある型が別の型に対してジェネリックであるとき、その別の型には小文字の名前を使い、それを型パラメーターと呼びます。 よくある例は、List、Maybe、Resultというカスタム型です。

-- Maybe is generic over the type a
type Maybe a
    = Nothing
    | Just a

someString : Maybe String
someString = Just "hello"

someInt : Maybe Int
someInt = Just 42

型パラメーターの名前について大切なのは、複数の文字を使えるということです。 唯一の制約は、小文字の名前でなければならないことです。 そのため、役に立つときには、説明的な名前を付けることがよくあります。

型は複数の別の型に対してジェネリックになれるので、複数の型パラメーターを持つこともできます。 その場合、それぞれ独立した型に違う小文字の名前を付けます。 独立しているからといって、同じ型になれないわけではありません。ただ、違う型になれるようになるだけです。

-- Result is generic over the types error and value
type Result error value
    = Ok value
    | Err error

レコードの型エイリアスも型パラメーターを持てますが、あまり一般的ではありません。

-- Event is generic over the type a
type alias Event a =
    { at : Time
    , data : a 
    }

関数における型パラメーター

型がジェネリックになれるのですから、関数も同様です。 ジェネリックな型を扱う関数を書くこともできます。たとえばMaybe.withDefaultです。

withDefault : a -> Maybe a -> a
withDefault default maybe =
    case maybe of
      Just value -> value
      Nothing -> default

他の関数を仮引数として受け取る関数は高階関数と呼ばれ、これらもジェネリックになれます。

map : (a -> b) -> Maybe a -> Maybe b
map function maybe =
  case maybe of
    Just value ->
      Just (function value)

    Nothing ->
      Nothing

説明

この演習では、宝物をしまっておくための、ジェネリックな(しかも魔法のような!)TreasureChestを書いていきます。

1. ジェネリックなカスタム型TreasureChestを定義する

単一のバリアントを持つ、カスタム型TreasureChestを定義します。

このバリアントには、関連付けられたStringの値を持たせます。この値は、宝箱のパスワードを保存するために使います。

このバリアントには、関連付けられたジェネリックな値も持たせます。この値は宝物を保存するために使います。 宝物はどんなものでもかまわないように、この値はジェネリックになっています。

2. getTreasure関数を定義する

この関数は2つの入力を受け取ります。

  • String(パスワードを試すためのもの)
  • ジェネリックなカスタム型のTreasureChest

この関数は、渡されたパスワードの試行を、TreasureChestの中のStringと照らし合わせます。

この関数はMaybeを返します。

パスワードが一致したら、TreasureChestから取り出したジェネリックな値(宝物です!)を持つJustを返します。

パスワードが一致しなければ、Nothingを返します。

3. multiplyTreasure関数を定義する

この(高階)関数は2つの入力を受け取ります。

  • ジェネリックな入力を1つ受け取り、同じジェネリック型のリストを返す掛け算用の関数
  • 同じジェネリック型を持つ、ジェネリックなカスタム型のTreasureChest

この関数は、宝箱の中の宝物を渡して、掛け算用の関数を呼び出します。

この関数は、元と同じパスワードを持ち、掛け算された宝物(戻り値)を持つ、新しいTreasureChestを返します。

GitHubで編集する リンクは新しいウィンドウまたはタブで開きます
Elm Exercism

宝箱を始める準備はできましたか?

Exercismに登録すれば、28個のコンセプト110個の演習、そして本物の人間によるメンタリングとともに、Elmを学んでマスターできます。すべて無料です。