2020-04-05 23:35:25
「第一級関数」というのを見ていく
はじめに
「第一級関数」というのは性質のことを意味するらしい。Microsoft によると以下の基準があるとのこと。
ファースト クラスのステータスの標準的な基準は次のとおりです。
- 関数を識別子にバインドすることはできますか。 つまり、名前を付けることができますか。
- 関数をリストなどのデータ構造に格納できますか。
- 関数呼び出しの引数として関数を渡すことはできますか。
- 関数呼び出しから関数を返すことはできますか。
Elixirで試してみる。この性質を持っているかは分かりませんが、関数型なので恐らく持っているでしょう。 カリー化の勉強中なので関数名や変数名が Curry だったりします。
使うモジュール
defmodule Curry do
def add(x,y) do
x+y
end
def cadd(x) do
fn y -> add(x,y) end
end
def callFunction(f) do
f.()
end
end
1つ1つ「多分こういうことだろう」というのを見ていく
関数を識別子にバインドすることはできますか
iex(20)> crry = Curry.cadd(10)
#Function<0.54427309/1 in Curry.cadd/1>
iex(21)> crry.(20)
30
iex(22)>
できてる。
関数をリストなどのデータ構造に格納できますか。
iex(15)> crry1 = Curry.cadd(1000)
#Function<0.54427309/1 in Curry.cadd/1>
iex(16)> crry2 = Curry.cadd(2000)
#Function<0.54427309/1 in Curry.cadd/1>
iex(17)> crry3 = Curry.cadd(3000)
#Function<0.54427309/1 in Curry.cadd/1>
iex(18)> sample = [crry1, c]
c/1 c/2 case/2 cd/1 ceil/1
clear/0 cond/1 continue/0 crry crry1
crry2 crry3
iex(18)> sample = [crry1, crry2, crry3]
[#Function<0.54427309/1 in Curry.cadd/1>,
#Function<0.54427309/1 in Curry.cadd/1>,
#Function<0.54427309/1 in Curry.cadd/1>]
iex(19)>
できてる。
関数呼び出しの引数として関数を渡すことはできますか。
以下のように実行する。確かに関数の引数に関数を渡せています。
/home/trial # iex curry.ex
Erlang/OTP 21 [erts-10.3.5.1] [source] [64-bit] [smp:2:2] [ds:2:2:10] [async-threads:1] [hipe]
Interactive Elixir (1.8.1) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> myFunc = fn -> "Hello World" end
#Function<20.128620087/0 in :erl_eval.expr/5>
iex(2)> Curry.callFunction(myFunc)
"Hello World"
iex(3)>
関数呼び出しから関数を返すことはできますか。
これは 1. で書いたカリー化の実装と同じでは・・・?
再掲
iex(20)> crry = Curry.cadd(10)
#Function<0.54427309/1 in Curry.cadd/1>
iex(21)> crry.(20)
30
iex(22)>
確かに 変数crry に無名関数を返しています。