質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.40%

  • Lua

    58questions

    Luaは、汎用のスクリプト言語の一つで、 移植性が高く、高速な実行速度などの特徴を持ち 手続き型・オブジェクト指向言語としても利用可能で 関数型言語、データ駆動型の要素も併せ持っている言語です。

Luaのカリー化関数について

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 1,187

keisukeoo

score 167

Luaの関数型言語としての特徴として、カリー化関数をサポート
していることがあげられますが、
この簡単なコード例を示して頂けませんか?
Lua言語で理解したいです。
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+3

Lua が関数型というのには、ちょっと引っかかりますが、とりあえず説明してみたいと思います。


カリー化というのは「 2 つ以上の引数を持つ関数を 1 つの引数の関数の組み合わせになおす」ことを言います。

次のような関数をカリー化してみます。
function plus(a, b)
   return a + b
end

print(plus(2, 3)) -- 5

カリー化は戻り値として関数を返すことによって実現します。
function cplus(a, b)
   return function(b) return a + b end
end

print(cplus(2)(3)) -- 5

plus(2, 3) と書いていたものが cplus(2)(3) と書けるようになりました。これがカリー化です。



このカリー化した関数を使ってみます。

まず、テーブルに関数を適用して新しいテーブルを返す関数mapを作成します。
関数型の機能を取り入れた言語では通常デフォルトであるのですが、 Lua の場合は自分で作る必要があります。
function map(func, array)
  local new_array = {}
  for i,v in ipairs(array) do
    new_array[i] = func(v)
  end
  return new_array
end

src = {1,2,3}
dest = map(function(x) return 2 + x end, src)
print(table.concat(dest,", "))    -- 3, 4, 5

map に渡す関数をカリー化した関数を変えます。
dest = map(cplus(2), src)
print(table.concat(dest,", "))    -- 3, 4, 5

map は引数を一つだけとる関数のみを受け付けるのですが、関数がカリー化してあることによって、そこに関数を渡せるようになっています。
このように関数がカリー化してあると引数として渡す際に柔軟に対応できるようになります。



関数型では高階関数といって関数を引数に渡すことがよくあります。その辺についても補足しておきます。

まず、関数型プログラミングのポイントに以下の点があります。 

関数は数学的な意味での関数 → 副作用を伴わない
  → 一度作成した変数は変更しない(参照透過性)

変数を変更しないというのは大きな制約で、関数型では ループ ができません。
カウンターやイテレーターといったものが使えないためです。

ループを一番よく使う場面というのはコレクション(Lua ではテーブル)の要素を処理していく場合だと思います。
そのため、関数型では map のような関数で関数を適用してデータ処理を行うという手法がよくとられています。


ちなみにコレクションの処理以外のループはどうするかというと「再帰」を使います。
再帰はループに比べるとスタックを積むのでメモリーを大量に消費してしまって不利です。そこで関数型の言語には「関数末尾の再帰最適化」の機能が求められます。
この機能は Lua にもあります。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2014/09/10 14:15

    とても親切な回答ありがとうございました!補足で色々説明してくださったおかげでイメージがつきました!ありがとうございました!

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.40%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る

  • Lua

    58questions

    Luaは、汎用のスクリプト言語の一つで、 移植性が高く、高速な実行速度などの特徴を持ち 手続き型・オブジェクト指向言語としても利用可能で 関数型言語、データ駆動型の要素も併せ持っている言語です。