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

もやもやエンジニア

IT系のネタで思ったことや技術系のネタを備忘録的に綴っていきます。フロント率高め。

Elixir 入門 その8 - Recursion

Loops through recursion

  • Elixirでは他の関数型言語と同じように繰り返し処理を行うためのForやWhileが無い。
  • 再帰を使って表現する。パターンマッチを効果的に使うことで可読性の高い再帰を表現できる。
defmodule Recursion do

  # ガードによって n が 1 以下の場合のみ呼ばれる。再帰の終わり。
  def print_multiple_times(msg, n) when n <= 1 do
    IO.puts msg
  end

  # 上の再帰の終了条件にかからない限りは自分を繰り返し呼ぶ
  def print_multiple_times(msg, n) do
    IO.puts msg
    print_multiple_times(msg, n - 1)
  end
end

Recursion.print_multiple_times("Hello!", 3)
> elixir recursion.exs
Hello!
Hello!
Hello!

Reduce and Map algorithms

defmodule Recursion do

  # パターンマッチでList内の要素がある限りは再帰で繰り返す。
  # head = 先頭の要素 tail = それ以外の要素が束縛されていて、
  # 次回の呼び出し時のarg1にtailを指定することで呼び出すたびにListの要素が減っていく
  def sum_list([head|tail], accumulator) do
    sum_list(tail, head + accumulator)
  end

  # Listの要素が空の場合は再帰の終了
  def sum_list([], accumulator) do
    accumulator
  end
end

IO.puts Recursion.sum_list([1,2,3,4,5], 0)
> elixir recursion.exs
15
  • mapの例
defmodule Recursion do

  # sum_listと似たような例。headは * 2しつつtailは再帰呼び出しの引数に渡す
  # 最終的にはリストの各要素がすべて * 2 される
  def double_each([head|tail]) do
    [head * 2|double_each(tail)]
  end

  # リストが空になったら再帰の終了
  def double_each([]) do
    []
  end

end

IO.inspect Recursion.double_each([1,2,3,4,5])
> elixir recursion.exs
[2, 4, 6, 8, 10]