Skip to content

Instantly share code, notes, and snippets.

@chooblarin
Last active August 29, 2015 14:27
Show Gist options
  • Save chooblarin/2432345f7b11629bafd9 to your computer and use it in GitHub Desktop.
Save chooblarin/2432345f7b11629bafd9 to your computer and use it in GitHub Desktop.

Elixir勉強会(社内向け)Aug 19 2015

前回までのあらすじ

  • Elixirがどこかで流行っているプログラミング言語だということがわかった
  • 動的型付けの関数型言語だった
  • Elixirの文法の雰囲気がちょっとわかった
  • 色々なことがほんのりとわかった気になれた
  • OTP

今回の目標

何か動くものをつくりたいのでもうちょっとその準備を整えましょう. 今日学ぶのは

  • Enumモジュール
  • パイプライン演算子

おさらい

データ構造

  • List
list1 = [1, 2, 3]
list2 = [1, true, 'nandemo', :ok, "🍣"]
  • Map
m = %{age: 26, gender: :male, locale: "ja"}
m[:age] # => 26
m[:gender] # => :male

制御構文

  • if式
result = if nil do
    "This won't be seen"
  else
    "This will"
  end
# result => "This will"

関数

fn arg1, arg2, .., , argN -> ... endで定義

add = fn a, b -> a + b end

add.(1, 2) # => 3

モジュール

defmodule <モジュール名> do ... endで定義

defmodule Math do
  def sum(a, b) do
    a + b
  end
end

パターンマッチング

[a, b, c] = [1, 2, 3]
a # => 1

[head | tail] = [1, 2, 3]
head # => 1
tail # => [2, 3]

That' it!

新たに学ぶ

  • 繰り返し処理はどうやるの
defmodule Recursion do
  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

elixir recursion.ex iex> Recursion.print_multiple_times("Yo", 5)

  • Enumモジュールはenumerableなアイテムを変形,並びかえ,グルーピング,フィルタリング,検索の関数を提供
  • Enumerableプロトコルを実装した任意のデータ型で動作できる
  • map, reduce, filterなどを用意
# map
Enum.map([1, 2, 3], fn x -> x * 2 end) # => [2, 4, 6]
Enum.map(%{1 => 2, 3 => 4}, fn {k, v} -> k * v end) # => [2, 12]
Enum.map(1..3, fn x -> x * 2 end) # => [2, 4, 6]

# reduce
Enum.reduce(1..10, 0, fn x, y -> x + y end) # => 55
Enum.reduce(1..10, 1, fn x, y -> x * y end) # => 3628800

# filter
Enum.filter(1..10, fn x -> rem(x, 2) == 0 end) # => [2, 4, 6, 8, 10]

Enumモジュールの関数はポリモーフィック

パイプライン演算子

  • |> これがパイプライン演算子
  • hoge |> fugahogefugaの第1引数に渡して処理
[1, 2, 3] |> Enum.map(fn x -> 2 * x end) # => [2, 4, 6]
[1, 2, 3] |> Enum.reduce(0, fn x, y -> x + y end) # => 6
1..10 |> Enum.filter(fn x -> rem(x, 2) == 0 end) # => [2, 4, 6, 8, 10]

1..10 |> Enum.filter(fn x -> rem(x, 2) == 0 end) |> Enum.reduce(0, fn x, y -> x + y end) # => 30

キャプチャ演算子

  • &これがキャプチャ演算子
  • 関数を作るときのショートカット
fun = &(&1 + 1) # fn x -> x + 1 end と同じ
fun.(1) #=> 2
1..10 |> Enum.filter(&(rem(&1, 2) == 0)) |> Enum.reduce(0, &+/2) # => 30

練習その1

  1. フィボナッチ数列をプリントするプログラムをつくってみましょう
  2. クイックソートするプログラムをつくってみましょう
defmodule Prac1 do
  def fib(0) do 0 end
  def fib(1) do 1 end
  def fib(n) do fib(n-1) + fib(n-2) end

  def qsort([]) do [] end
  def qsort([h|tail]) do
    {left, right} = Enum.partition(tail, &(&1 < h))
    qsort(left) ++ [h] ++ qsort(right)
  end
end

練習その2

素数を判定するプログラムをつくってみましょう

defmodule Prac2 do
  def prime?(2) do true end
  def prime?(n) when n < 2 do false end
  def prime?(n) when rem(n, 2) == 0 do false end
  def prime?(n) do check(3, n) end

  defp check(a, b) do
    if a * a <= b do
      if rem(b, a) == 0 do
        false
      else
        check(a + 2, b)
      end
    else
      true
    end
  end
end

# 1..100 |> Enum.filter(&(Prac2.prime?/1))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment