-
-
Save niku/9971916 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
defmodule Fibcalc do | |
def calc_fibs(list) do | |
# 今回「プロセスを生成して,生成したプロセスの中で計算して,その結果を送ってもらう」という処理をこれから書く. | |
# 送ってもらう先は自分になるので,自分のpidを覚えておく. | |
me = self | |
# ```[1,2,3] |> Enum.map(fn (elem) -> elem + 1 end)``` | |
# は | |
# ```Enum.map([1,2,3], fn (elem) -> elem + 1 end)``` | |
# と同じ.|>の左側の結果が,|>の右側の式の第一引数になる. | |
# 「各リストに1を足して,それから2を掛ける」 | |
# ```[1,2,3] |> Enum.map(fn (elem) -> elem + 1 end) |> Enum.map(fn (elem) -> elem * 2 end)``` | |
# といったような処理の流れを書くのに便利 | |
list | |
|> | |
Enum.map(fn (elem) -> | |
# spawn(body)でプロセスを生成して,bodyの中のことをやってもらう | |
spawn fn -> | |
# send(pid, body)でpidへbodyを送る | |
# ここではpidにmeを指定しているので, | |
# 自分へ {spawnした先のpid, 元の値,計算結果} のタプルを送る | |
send(me, {self, elem, fib(elem)}) | |
end | |
end) | |
# listの数だけ結果が送られてくるはずなので待つ | |
waitn(Enum.count(list)) | |
end | |
# ```fib(0)```で関数fibに渡ってくる変数が0の場合,という処理を書ける | |
def fib(0), do: 1 | |
def fib(1), do: 1 | |
def fib(n), do: fib(n-1) + fib(n-2) | |
defp waitn(0), do: IO.puts "done!" | |
defp waitn(n) do | |
IO.puts "remain #{n} times..." | |
# sendされてきたやつはreceiveで受け取れる | |
# sendされてきたやつのことをメッセージという. | |
# 今回は自分に対してメッセージを送ったので,自分で受け取る. | |
# メッセージが何個たまっていても,receive1回につき1つのメッセージしか受け取らない(受け取れない) | |
receive do | |
{pid, number, result} -> IO.inspect {pid, number, result} | |
end | |
# 複数回メッセージを受け取りたい場合,Elixirでは再帰するのが一般的 | |
waitn(n-1) | |
end | |
end | |
Fibcalc.calc_fibs([12, 3, 11, 4, 24, 31, 28, 10]) | |
#> remain 8 times... | |
#> {#PID<0.41.0>, 12, 233} | |
#> remain 7 times... | |
#> {#PID<0.42.0>, 3, 3} | |
#> remain 6 times... | |
#> {#PID<0.43.0>, 11, 144} | |
#> remain 5 times... | |
#> {#PID<0.44.0>, 4, 5} | |
#> remain 4 times... | |
#> {#PID<0.48.0>, 10, 89} | |
#> remain 3 times... | |
#> {#PID<0.45.0>, 24, 75025} | |
#> remain 2 times... | |
#> {#PID<0.47.0>, 28, 514229} | |
#> remain 1 times... | |
#> {#PID<0.46.0>, 31, 2178309} | |
#> done! |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment