info

luaによる関数型風プログラミング

いろいろ再帰

function fact (x)
	if x == 1 then
		return 1
	end
	return x * fact(x - 1)
end

function triangle(x)
	if x == 0 then
		return 0
	end
	return x + triangle(x - 1)
end


function fib (x)
	if x < 2 then
		return x
	end
	return fib(x - 1) + fib(x - 2)
end

print(fact(10))
print(triangle(10))
print(fib(31))

アキュームレータージェネレーター

function acc (n)
	return function (i) n = n + i; return n; end
end

foo = acc(5)

print(foo(2))
print(foo(6))
print(foo(5))
print(foo(1))

メモ化関数と、たらいまわし

function tak(x, y, z)
	if x <= y then
		return z
	else
		return tak(tak(x - 1, y, z), tak(y - 1, z, x), tak(z - 1, x, y))
	end
end


function tarai(x, y, z)
	if x <= y then
		return y
	else
		return tarai(tarai(x - 1, y, z), tarai(y - 1, z, x), tarai(z - 1, x, y))
	end
end

--http://stackoverflow.com/questions/129877/how-do-i-write-a-generic-memoize-function
function varg_tostring(...)
    local s = select(1, ...)
    for n = 2, select('#', ...) do
        s = s..","..select(n,...)
    end
    return s
end

function memoize(f)
    local cache = {}
    return function (...)
        local al = varg_tostring(...)
        if cache[al] then
            return cache[al]
        else
            local y = f(...)
            cache[al] = y
            return y
        end
    end
end





print(tak(18, 9, 0))
print(tarai(12, 6, 0))

tak = memoize(tak)
print(tak(192,96,0))
tarai = memoize(tarai)
print(tarai(192,96,0))

fizzbuzz

require "std"

--http://lua-users.org/wiki/RangeIterator
function range(a, b, step)
  if not b then
    b = a
    a = 1
  end
  step = step or 1
  local f =
    step > 0 and
      function(_, lastvalue)
        local nextvalue = lastvalue + step
        if nextvalue <= b then return nextvalue end
      end or
    step < 0 and
      function(_, lastvalue)
        local nextvalue = lastvalue + step
        if nextvalue >= b then return nextvalue end
      end or
      function(_, lastvalue) return lastvalue end
  return f, nil, a - step
end

print(map(function (x)
	if x % 15 == 0 then
		return "fizzbuzz"
	elseif x % 5 == 0 then
		return "buzz"
	elseif x % 3 == 0 then
		return "fizz"
	else
		return x
	end
end, range, 1, 100, 1))