Lua/MoonScriptで部分関数

昨日の続き。

util = require 'util'
import Function, Switch, Case, Delay, List, Array, Sequence from util
_ = util.it
require 'std'

print '# Function combination'
print "(_ + 5 .. _ * 2)(1) ==> #{(_ + 5 .. _ * 2)(1)}"

print '# Partial function'
print nat\map Switch {
  Case (_ % 15)\eq(0), -> 'FizzBuzz'
  Case (_ %  3)\eq(0), -> 'Fizz'
  Case (_ %  5)\eq(0), -> 'Buzz'
  _
}

出力

# Function combination
(_ + 5 .. _ * 2)(1) ==> 7
# Partial function
[1,2,Fizz,4,Buzz,Fizz,7,8,Fizz,Buzz,...]

_ = util.itは Function((...) -> ...) のエイリアスで、プレースホルダーになる。

_ + 5 ==> Function (x) -> x + 5
_ + 5 .. _ * 2 ==> Function (x) -> (x * 2) + 5
(_ % 15)\eq(0) ==> Function (x) -> x % 15 == 0

Luaの制限から (1 / _) といったことはできないが、代わりに (_\inv!) を使える。

Caseは部分関数を作成する。SwitchやorElseを使って部分関数を結合できる。

MoonScriptではファットアロー記法を使って関数を簡潔に記述できるので、こんなこともできる。

namelist = List\Table {
  {id: 1, name: 'Alice', age: 19}
  {id: 2, name: 'Bob', age: 20}
  {id: 3, name: 'Catherine', age: 18}
  {id: 4, name: 'Dorothy', age: 21}
}

namelist\filter(=> @age < 20)\orderBy(=> @age)\select(=> @name)\each print