とりあえず一通り読み終わった。けど、第II部の並行プログラミング以降はかなり消化不良。特にマクロのあたりなんかはほとんどついていけなかった。
まあ、いい。今年はまだ10カ月以上ある。少しずつやっていこう。
[amazonjs asin=”4274219151″ locale=”JP” title=”プログラミングElixir”]
takatoh's blog – Learning programming languages.
とりあえず一通り読み終わった。けど、第II部の並行プログラミング以降はかなり消化不良。特にマクロのあたりなんかはほとんどついていけなかった。
まあ、いい。今年はまだ10カ月以上ある。少しずつやっていこう。
[amazonjs asin=”4274219151″ locale=”JP” title=”プログラミングElixir”]
defmodule ASCII do
def is_printable(charlist) do
charlist
|> Enum.map(&printable?/1)
|> Enum.all?
end
defp printable?(c) do
(32 <= c) and (c <= 126)
end
end
^o^ > iex practice_11_1.exs
Eshell V8.0 (abort with ^G)
Interactive Elixir (1.3.4) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> ASCII.is_printable('hello')
true
iex(2)> ASCII.is_printable('hello\n')
false
defmodule Order do
def sales_tax(orders, tax_rates) do
orders
|> Enum.map(fn o -> {o, tax_rate(o, tax_rates)} end)
|> Enum.map(fn {o, tax_rate}
-> Keyword.put(o, :total_amount, add_tax(o, tax_rate)) end)
end
defp tax_rate(order, rates) do
ship_to = Keyword.get(order, :ship_to)
Keyword.get(rates, ship_to, 0.0)
end
defp add_tax(order, tax_rate) do
Keyword.get(order, :net_amount) * (1.0 + tax_rate)
end
end
tax_rates = [ NC: 0.075, TX: 0.08 ]
orders = [
[ id: 123, ship_to: :NC, net_amount: 100.00 ],
[ id: 124, ship_to: :OK, net_amount: 35.50 ],
[ id: 125, ship_to: :TX, net_amount: 24.00 ],
[ id: 126, ship_to: :TX, net_amount: 44.80 ],
[ id: 127, ship_to: :NC, net_amount: 25.00 ],
[ id: 128, ship_to: :MA, net_amount: 10.00 ],
[ id: 129, ship_to: :CA, net_amount: 100.00 ],
[ id: 130, ship_to: :NC, net_amount: 50.00 ] ]
Order.sales_tax(orders, tax_rates)
|> Enum.each(&IO.inspect/1)
^o^ > elixir practice_10_4.exs [total_amount: 107.5, id: 123, ship_to: :NC, net_amount: 100.0] [total_amount: 35.5, id: 124, ship_to: :OK, net_amount: 35.5] [total_amount: 25.92, id: 125, ship_to: :TX, net_amount: 24.0] [total_amount: 48.384, id: 126, ship_to: :TX, net_amount: 44.8] [total_amount: 26.875, id: 127, ship_to: :NC, net_amount: 25.0] [total_amount: 10.0, id: 128, ship_to: :MA, net_amount: 10.0] [total_amount: 100.0, id: 129, ship_to: :CA, net_amount: 100.0] [total_amount: 53.75, id: 130, ship_to: :NC, net_amount: 50.0]
total_amount が最初に追加されちゃってるのがちょっと気に入らないけど、まあいいか。
以前に作った span 関数と内包表記を使って 2 から n までの素数。
defmodule MyList do
def span(from, to) when from == to, do: [to]
def span(from, to), do: [from | span(from + 1, to)]
def primes(n) do
for x <- span(2, n), is_prime(x), do: x
end
defp is_prime(2), do: true
defp is_prime(3), do: true
defp is_prime(n) do
m = div(n, 2)
Enum.all?(Enum.map(span(2, m), fn x -> rem(n, x) != 0 end))
end
end
^o^ > iex practice_10_3.exs Eshell V8.0 (abort with ^G) Interactive Elixir (1.3.4) - press Ctrl+C to exit (type h() ENTER for help) iex(1)> MyList.primes(50) [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47]
flattenn。
defmodule MyList do
def flatten(list) do
_flatten(list, [])
end
defp _flatten([], r) do
Enum.reverse(r)
end
defp _flatten([head|tail], r) do
if is_list(head) do
_flatten(tail, Enum.reverse(flatten(head)) ++ r)
else
_flatten(tail, [head | r])
end
end
end
^o^ > iex practice_10_2.exs Eshell V8.0 (abort with ^G) Interactive Elixir (1.3.4) - press Ctrl+C to exit (type h() ENTER for help) iex(1)> MyList.flatten([1, [2, 3, [4] ], 5, [[[6]]]]) [1, 2, 3, 4, 5, 6]
sudo userdel コマンドを使う。
takatoh@apostrophe $ sudo userdel -r sombrero [sudo] password for takatoh: userdel: sombrero のメールスプール (/var/mail/sombrero) がありません
-r はホームディレクトリとメールスプールも削除するオプション。
次の関数を、ライブラリやリスト内包表記を利用せずに実装しろ、と。
defmodule MyList do
def all?([]), do: true
def all?([head | tail]) when head, do: all?(tail)
def all?(_list), do: false
def each([], _func) do
end
def each([head|tail], func) do
func.(head)
each(tail, func)
end
def filter([], _prod) do
[]
end
def filter([head|tail], prod) do
if prod.(head) do
[head | filter(tail, prod)]
else
filter(tail, prod)
end
end
def split(list, n), do: _split({[], list}, n)
defp _split(result, 0), do: result
defp _split(result = {_left, []}, _), do: result
defp _split({left, [head|tail]}, n), do: _split({left ++ [head], tail}, n - 1)
def take(list, n) do
{result, _} = split(list, n)
result
end
end
順番に行ってみよう。まずは all?。
^o^ > iex practice_10_1.exs Eshell V8.0 (abort with ^G) Interactive Elixir (1.3.4) - press Ctrl+C to exit (type h() ENTER for help) iex(1)> MyList.all?([true, true, true]) true iex(2)> MyList.all?([true, false, true]) false
つぎに each。
iex(3)> MyList.each([1, 2, 3], &IO.puts/1) 1 2 3 nil
nil は each 自体の返り値かな。
つぎ、filter。
iex(4)> MyList.filter([1, 2, 3, 4, 5], &(&1 > 2)) [3, 4, 5]
split。
iex(5)> MyList.split([1, 2, 3, 4, 5], 2)
{[1, 2], [3, 4, 5]}
最後に take。
iex(6)> MyList.take([1, 2, 3, 4, 5], 3) [1, 2, 3]
defmodule MyList do
def map([], _func), do: []
def map([head|tail], func), do: [func.(head) | map(tail, func)]
def reduce([], value, _func) do
value
end
def reduce([head|tail], value, func) do
reduce(tail, func.(head, value), func)
end
def span(from, to) when from == to, do: [to]
def span(from, to), do: [from | span(from + 1, to)]
end
^o^ > iex practice_7_4.exs Eshell V8.0 (abort with ^G) Interactive Elixir (1.3.4) - press Ctrl+C to exit (type h() ENTER for help) iex(1)> MyList.span(3, 7) [3, 4, 5, 6, 7]
map も reduce も使ってないな。
今度の練習問題はカエサル暗号だ。
defmodule MyList do
def map([], _func), do: []
def map([head|tail], func), do: [func.(head) | map(tail, func)]
def reduce([], value, _func) do
value
end
def reduce([head|tail], value, func) do
reduce(tail, func.(head, value), func)
end
def caesar(list, n) do
map(list, fn c -> rem(c + n - ?a, 26) + ?a end)
end
end
^o^ > iex practice_7_3.exs
Eshell V8.0 (abort with ^G)
Interactive Elixir (1.3.4) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> MyList.caesar('ryvkve', 13)
'elixir'
defmodule MyList do
def reduce([], value, _func) do
value
end
def reduce([head|tail], value, func) do
reduce(tail, func.(head, value), func)
end
def max([head|tail]) do
reduce(tail, head, &_max/2)
end
defp _max(a, b) when a < b, do: b
defp _max(a, _), do: a
end
^o^ > iex practice_7_2.exs Eshell V8.0 (abort with ^G) Interactive Elixir (1.3.4) - press Ctrl+C to exit (type h() ENTER for help) iex(1)> MyList.max([1,2,3,4,5]) 5 iex(2)> MyList.max([5,4,3,2,1]) 5