Luaで関数型プログラミングサポート

新しい言語を覚える段階では、別の言語と比べすぎない方がいいと思ってるので、今まで、欲しいと思った関数が無くても、Luaの概念を知るためになるべく素のLuaの範囲で書いてきました。(あえて、Lisp的に書くために関数を追加するようなことは避けてきました)

しかし、いくつかLuaでWebアプリケーションを書いてきたので、そろそろお遊びをしてもいい頃かと思い、map reduce apply を実装してみました。utilsというモジュールを作りました。

utils.lua
module(..., package.seeall)

function clone(list)
  local result = {}
  for k, v in pairs(list) do
    result[k] = v
  end
  return result
end

function map(f, list)
  local result = {}
  for _, v in pairs(list) do
    table.insert(result, f(v))
  end
  return result
end

function reduce(f, list)
  local list = clone(list)
  local result = table.remove(list)
  for _, v in pairs(list) do
    result = f(result, v)
  end
  return result
end

function apply(f, args)
  return f(unpack(args))
end

map は、一つしかリストを取得できない手抜き版です。


test.lua

使い方

require "utils"
local ary = {1, 2, 3, 4, 5}
local ret = utils.map(function(x) return x * 2 end, ary)
print("map:", table.concat(ret, ", "))
--> map:    2, 4, 6, 8, 10
print("sum:", utils.reduce(function(x, y) return x + y end, ary))
--> sum:    15
print("max:", utils.apply(math.max, ary))
--> max:    5

LuaでWebアプリケーションを書く中で、素のLuaに接してみて、やはりfor文を沢山書く必要があるのが、面倒だなと感じました。だいたい、Webアプリケーションでのデータ操作なんて、写像が大半なんだから、mapを使った方が分かり易いと思う。とにかく、関数型プログラミングのためのサポート関数も簡単に書けました。

stdlib

stdlibというLuaを便利にするライブラリがありました。

stdlib is a library of modules for common programming tasks, including list, table and functional operations, regexps, objects, pretty-printing and getopt. The whole thing can be loaded with ‘require “std”‘, or modules can be used individually.

LuaForge: stdlib – general Lua libraries: Project Info

もちろん、リスト操作系のmapとか、reverseとか、filterとか、fold(r|l)とかだけでなく、tostringの拡張とかも入ってるみたいです。prototype.js的に、標準ライブラリの中まで拡張しているようです。また、機会があれば、中身をよく見てみたいです。こんなに、豪勢に拡張して、Luaの良さを侵食してないかちょっと心配w

コメントする

メールアドレスが公開されることはありません。 が付いている欄は必須項目です


The reCAPTCHA verification period has expired. Please reload the page.

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください