wslでelixir その46

# 概要
wsl(wsl2じゃない)で、elixirやってみた。
Cizen、やってみた。

# 参考にしたページ

https://qiita.com/ryo33/items/3d3fc82cdcb929e0b9ec


# 手順

```
$ mix new testcizen

$ cd testcizen

defp deps do
	[
		{:cizen, "~> 0.14.1"}
	]
end

$ mix deps.get

$ iex -S mix

```

# サンプルコード

```

defmodule BorrowChopstick do
	defstruct [:chopstick_id]
	use Cizen.Request
	defresponse LendChopstick, :request_id do
		defstruct [:request_id]
	end
end

defmodule ReturnChopstick do
	defstruct [:chopstick_id]
end

defmodule Chopstick do
	use Cizen.Automaton
	defstruct []
	alias Cizen.Effects.{Dispatch, Receive, Subscribe}
	alias Cizen.{Event, Filter}
	@impl true
	def spawn(id, %__MODULE__{}) do
		perform id, %Subscribe{
			event_filter: Filter.any([
				Filter.new(fn %Event{body: %BorrowChopstick{chopstick_id: ^id}} -> 
					true 
				end),
				Filter.new(fn %Event{body: %ReturnChopstick{chopstick_id: ^id}} -> 
					true 
				end)
			])
		}
		:available
	end
	@impl true
	def yield(id, :available) do
		received = perform id, %Receive{
			event_filter: Filter.new(fn %Event{body: %BorrowChopstick{}} -> 
				true 
			end)
		}
		alias BorrowChopstick.LendChopstick
		perform id, %Dispatch{
			body: %LendChopstick{
				request_id: received.id
			}
		}
		:not_available
	end
	@impl true
	def yield(id, :not_available) do
		perform id, %Receive{
			event_filter: Filter.new(fn %Event{body: %ReturnChopstick{}} -> 
				true 
			end)
		}
		:available
	end
end

defmodule Philosopher do
	use Cizen.Automaton
	defstruct [:name, :left_chopstick, :right_chopstick]
	alias Cizen.Effects.{Request, Dispatch}
	@impl true
	def spawn(_id, struct) do
		{:hungry, struct}
	end
	@impl true
	def yield(id, {:hungry, struct}) do
		%__MODULE__{
			name: name,
			left_chopstick: left_chopstick,
			right_chopstick: right_chopstick
		} = struct
		IO.puts("#{name} is hungry.")
		perform id, %Request{
			body: %BorrowChopstick{
				chopstick_id: left_chopstick
			}
		}
		IO.puts("#{name} has a chopstick in their left hand.")
		perform id, %Request{
			body: %BorrowChopstick{
				chopstick_id: right_chopstick
			}
		}
		IO.puts("#{name} has chopstics in both hands.")
		{:eating, struct}
	end
	@impl true
	def yield(id, {:eating, struct}) do
		%__MODULE__{
			name: name,
			left_chopstick: left_chopstick,
			right_chopstick: right_chopstick
		} = struct
		IO.puts("#{name} is eating.")
		perform id, %Dispatch{
			body: %ReturnChopstick{
				chopstick_id: left_chopstick
			}
		}
		perform id, %Dispatch{
			body: %ReturnChopstick{
				chopstick_id: right_chopstick
			}
		}
		{:hungry, struct}
	end
end

defmodule Dining do
	use Cizen.Effectful
	alias Cizen.Effects.{All, Start}
	def run do
		handle fn id ->
			chopstick_1 = perform id, %Start{saga: %Chopstick{}}
			chopstick_2 = perform id, %Start{saga: %Chopstick{}}
			chopstick_3 = perform id, %Start{saga: %Chopstick{}}
			chopstick_4 = perform id, %Start{saga: %Chopstick{}}
			chopstick_5 = perform id, %Start{saga: %Chopstick{}}
			philosophers = [
				%Philosopher{
					name: "Plato",
					left_chopstick: chopstick_1,
					right_chopstick: chopstick_2
				},
				%Philosopher{
					name: "Konfuzius",
					left_chopstick: chopstick_2,
					right_chopstick: chopstick_3
				},
				%Philosopher{
					name: "Socrates",
					left_chopstick: chopstick_3,
					right_chopstick: chopstick_4
				},
				%Philosopher{
					name: "Voltaire",
					left_chopstick: chopstick_4,
					right_chopstick: chopstick_5
				},
				%Philosopher{
					name: "Descartes",
					left_chopstick: chopstick_5,
					right_chopstick: chopstick_1
				}
			]
			perform id, %All{
				effects: Enum.map(philosophers, &(%Start{saga: &1}))
			}
			receive do
				_ -> 
					:ok
			end
		end
	end
end





```


# 実行結果

```
Interactive Elixir (1.13.4) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> Dining.run
Plato is hungry.
Konfuzius is hungry.
Socrates is hungry.
Voltaire is hungry.
Descartes is hungry.
Plato has a chopstick in their left hand.
Konfuzius has a chopstick in their left hand.
Socrates has a chopstick in their left hand.
Voltaire has a chopstick in their left hand.
Descartes has a chopstick in their left hand.

BREAK: (a)bort (A)bort with dump (c)ontinue (p)roc info (i)nfo
       (l)oaded (v)ersion (k)ill (D)b-tables (d)istribution
a
```

以上。