秘密

秘密

学習演習

はじめに

無名関数

Elixirでは、関数は第一級オブジェクトとして扱われます。つまり、次のようなことができます。

  • 名前付き関数も無名関数も、変数に代入できます。
  • 名前付き関数も無名関数も、データと同じように、引数や戻り値として受け渡すことができます。
  • 無名関数は、動的に作成できます。

無名関数は、名前付き関数とは異なり、静的な参照を持ちません。変数に代入するか、その場で呼び出す場合にのみ利用できます。

無名関数は、次のような場面で使うことがあります。

  • レキシカルスコープ(クロージャーとも呼ばれます)を使ってデータを隠す。
  • 実行時に動的に関数を作成する。

無名関数は予約語fnで始まり、引数は->トークンで関数の本体と区切られ、endで終わります。名前付き関数と同じく、関数内の最後の式は、呼び出し元に_暗黙的に返され_ ます。

関数の参照を呼び出すには、参照を保持する変数と引数のリストの間に.を書く必要があります。

function_variable = fn param ->
  param + 1
end

function_variable.(1)
# => 2

さらに、省略記法のキャプチャ構文を使うと、もっと簡潔に書くこともできます。

variable = &(&1 + 1)

variable.(1)
# => 2

ビット操作

Elixirには、ビットを扱うための多くの関数が用意されており、それらは_Bitwise_モジュールにあります。

  • band/2: ビット単位のAND
  • bsl/2: ビット単位の左シフト
  • bsr/2: ビット単位の右シフト
  • bxor/2: ビット単位のXOR
  • bor/2: ビット単位のOR
  • bnot/1: ビット単位のNOT

ビット演算の関数を使う例を次に示します。

Bitwise.bsl(1, 3)
# => 8

ビット演算の関数は、すべて整数に対してのみ動作します。

Elixirのバージョン1.9以前を使っている場合は、_Bitwise_モジュールを利用するために、モジュール定義の先頭でrequire Bitwiseを呼び出す必要があります。

説明

この演習では、データを変換することで動作する暗号化デバイスのソフトウェアを書くという課題に取り組みます。より単純な関数を組み合わせて複雑な関数を柔軟に作る方法が必要です。

各タスクでは、呼び出し元のスコープから呼び出せる無名関数を返します。

どの関数も整数の引数を取るものとします。また、Elixirでビット演算を行う場合にも整数が適しています。

1. 加算器を作る

Secrets.secret_add/1を実装します。これは、1つの引数を取り、それにsecret_addへ渡された引数を加算する関数を返します。

adder = Secrets.secret_add(3)
adder.(2)
# => 5

2. 減算器を作る

Secrets.secret_subtract/1を実装します。これは、1つの引数を取り、その引数からsecret_subtractへ渡された秘密の値を引く関数を返します。

subtractor = Secrets.secret_subtract(2)
subtractor.(3)
# => 1

3. 乗算器を作る

Secrets.secret_multiply/1を実装します。これは、1つの引数を取り、それにsecret_multiplyへ渡された秘密の値を掛ける関数を返します。

multiplier = Secrets.secret_multiply(7)
multiplier.(3)
# => 21

4. 除算器を作る

Secrets.secret_divide/1を実装します。これは、1つの引数を取り、それをsecret_divideへ渡された秘密の値で割る関数を返します。

divider = Secrets.secret_divide(3)
divider.(32)
# => 10

出力が他の関数の期待する入力と互換になるように、整数除算を利用します。

5. 「and」を行う関数を作る

Secrets.secret_and/1を実装します。これは、1つの引数を取り、その引数とsecret_andへ渡された秘密の値に対してビット単位の_and_演算を行う関数を返します。

ander = Secrets.secret_and(1)
ander.(2)
# => 0

6. 「xor」を行う関数を作る

Secrets.secret_xor/1を実装します。これは、1つの引数を取り、その引数とsecret_xorへ渡された秘密の値に対してビット単位の_xor_演算を行う関数を返します。

xorer = Secrets.secret_xor(1)
xorer.(3)
# => 2

7. 関数を組み合わせる関数を作る

Secrets.secret_combine/2を実装します。これは、1つの引数を取り、secret_combineへ渡された2つの関数を順番にその引数へ適用する関数を返します。

add_one = Secrets.secret_add(1)
multiply_by_2 = Secrets.secret_multiply(2)
combined = Secrets.secret_combine(add_one, multiply_by_2)

combined.(3)
# => 8
GitHubで編集する リンクは新しいウィンドウまたはタブで開きます
Elixir Exercism

秘密を始める準備はできましたか?

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