JavaScriptは関数型言語の特徴を取り入れていると思いますが、純粋な関数型言語ではありません。通常はオブジェクト言語としてプログラミングするかと思います。しかし今、そしてこれからのトレンドは関数型言語と言われています。 そこでJavaScriptでより関数型言語的なプログラミングを可能にするfn.jsを使ってみましょう。慣れるまでは戸惑うかも知れませんが、面白いプログラミングができそうです。

試し中。

fn.jsのインストール

fn.jsはクライアント/サーバサイドの両方で利用できます。クライアントサイドの場合は単純に読み込むか、require.jsが使えます。

<script src="path/to/fn.js"></script>
// または
<script>
require.config({
	paths: {
		fn: 'path/to/fn'
	}
});
define(['fn'], function (fn) {
	// fn now available
});
</script>

サーバサイドはもちろんnpmです。

$ npm install fn.js
var fn = require('fn.js');

これで準備は完了で、いずれもfnというグローバル変数ができます。

fn.jsの使い方

まずは引数を配列化するtoArrayを見てみます。

var echo = function () {
	return fn.toArray( arguments );
};
echo( 1, 2, 3 ); // [ 1, 2, 3 ]

こんな感じで引数は自由な個数とれるようになっています。

fn.typeは型を返します。

fn.type( 'Bill' ); // "string"
fn.type( 3 ); // "number"
fn.type( {} ); // "object"
fn.type( [] ); // "array"
fn.type( function () {} ); // "function"
fn.type( null ); // "null"
fn.type( undefined ); // "undefined"
fn.type( /Hello World/i ); // "regexp"
fn.type( new Date() ); // "date"

同様にfn.isは検証です。

fn.is( 'Bill', 'string' ); // true
fn.is( 3, 'undefined' ); // false
fn.is( {}, 'object' ); // true
fn.is( [], 'function' ); // false
fn.is( function () {}, 'function' ); // true
fn.is( null, 'undefined' ); // false
fn.is( undefined, 'null' ); // false
fn.is( /Hello World/i, 'regexp' ); // true
fn.is( new Date(), 'number' ); // false

fn.applyは指定した関数に引数を渡して実行します。プラグインなどを作る際に使えそうですね。

var fullname = function ( firstName, lastName ) {
	return firstName + ' ' + lastName;
};

fn.apply( fullname, [ 'Bill', 'Smith' ] ); // "Bill Smith"

fn.concatは配列を連結します。

fn.concat( [ 'a', 1 ], [ 'b', 2 ], [ 'c', 3 ] ); // [ 'a', 1, 'b', 2, 'c', 3 ]

fn.partialはデフォルト値のように使えます。

var fullName = function ( firstName, lastName ) {
	return firstName + ' ' + lastName;
};

var billName = fn.partial( fullName, 'Bill' );

billName( 'Smith' ); // "Bill Smith"
billName( 'Clinton' ); // "Bill Clinton"

関数型言語というとカリー化が取り上げられるようですが、fn.jsでももちろんあります。

var fullName = fn.curry(function ( firstName, middleName, lastName ) {
	return firstName + ' ' middleName + ' ' + lastName;
});

var billName = fullName( 'Bill' );

billName( 'Damon' )( 'Smith' ); // "Bill Damon Smith"
billName( 'Jefferson', 'Clinton' ); // "Bill Jefferson Clinton"
fullName( 'Jenn', 'Anne', 'Cochran' ); // "Jenn Anne Cochran"
fullName( 'Jenn', 'Anne' )( 'Cochran' ); // "Jenn Anne Cochran"

f( a, b ) = c という関数 f があるときに、F( a ) = g ただし、g( b ) = c という関数 g が得られる関数 F を定義した場合、F は、f をカリー化したものである。

via カリー化 - Wikipedia

その他にも下記のような関数があります。

  • fn.properties( object )
  • fn.each( handler, collection, [ params ] )
  • fn.reduce( handler, collection, accumulator, [ params ] )
  • fn.filter( expression, collection )
  • fn.map( handler, collection, [ params ] )
  • fn.reverse( array )
  • fn.compose( …functions )
  • fn.pipeline( …functions )
  • fn.prop( name, property )
  • fn.merge( …objects )
  • fn.memoize( handler, [ serializer ] )
  • fn.flip( handler )
  • fn.delay( handler, msDelay )
  • fn.delayFor( msDelay, handler )
  • fn.delayed( handler, msDelay )
  • fn.delayedFor( msDelay, handler )
  • fn.async( handler )
  • fn.throttle( handler, msDelay )
  • fn.debounce( handler, msDelay )

fn.jsはもちろん第一級関数を扱えるようになっています。ScalaやHaskellなどで注目を集めている関数型言語をJavaScriptプログラミングにも取り入れるためにfn.jsを使ってみるのはいかがでしょうか。

fn.jsはJavaScript製、MIT Licenseのオープンソース・ソフトウェアです。

fn.js | A JavaScript library built to encourage a functional programming style & strategy. eliperelman/fn.js