Scalaっぽく書けるライブラリ作ってみました。
Scalikeです。
- Optional (Optionは予約語なのでOptionalに)
- Either
- Try
- Future
インストール
$ npm install scalike
型ファイル
$ tsd install scalike
Optional
Optionalは、値があるかどうかを表すクラスです。SomeかNoneになります。
///<reference path='./typings/scalike/scalike.d.ts'/>
import {Optional, Some, None} from 'scalike';
Optional(1) // Some(1)
Optional(null) // None
Optional(undefined) // None
こんな感じで実行。(出力したいならconsole.logで)
$ tsc foo.ts --module commonjs && node foo.js
Scalaのメソッドが一通り使えます。
Optional(1).getOrElse(0) // 1
Optional(null).getOrElse(0) // 0
Optional(1).map(x => x + 1).getOrElse(0) // 2
Optional(null).orElse(Optional(1)).getOrElse(0) // 1
Optional(1).exists(x => x === 1) // true
for式がないので、便利っぽいメソッドを追加しています。
apply1/apply2
Optional(1).apply1(Optional(2), (a, b) => a + b) // Some(3);
Optional(1).apply1(None, (a, b) => a + b) // None;
途中でNoneになったらそれ以降はNoneなので処理されません。
もっと繋げたいときはchain。(scalazのApplicativeBuilder参考させていただきました)
Optional(1)
.chain(Optional(2))
.chain(Optional(3))
.run((a, b, c) => a + b + c) // Some(6)
詳しくはテストを見てください。
Either
EitherはAとB2つの型を取って、どっちか表すクラスです。
LeftがAでRightがBです。Rightが正解と右を掛けていて右に正しい?値を入れるのが通例です。
バリデーションの結果でよく使われたりします。
///<reference path='./node_modules/scalike/dist/scalike.d.ts'/>
import {Either, Right, Left} from 'scalike';
function validate(x: number): Either<string, number> {
return x !== 1 ? Left<string, number>('this is not 1') : Right<string, number>(x)
}
validate(1).right().getOrElse(0) // 1
validate(2).left().getOrElse("err") // "this is not 1"
詳しくはテストを見てください。
Try
Tryは例外を包んでくれるクラスです。
成功すればSuccessになり、例外が起きるとFailureとなります。
import {Try, Success, Failure} from 'scalike';
Try(() => 1) // Success(1)
Try(() => eval("1 +")) // Failure(SyntaxError)
Try(() => 1).getOrElse(0) // 1
Try(() => 1).map(x => x + 1).getOrElse(0) // 2
Try(() => eval("1 +")).getOrElse(0) // 0
詳しくはテストを見てください。
Future
処理が終わったか分からない状態を表せるもの。
ES6のPromiseをラップして作っています。
Promiseか、関数を渡すことができます。
import {Future} from 'scalike';
function getGithub(): Promise<Response> {
return fetch('https://github.com/');
}
Future(getGithub())
.map(response => response.status)
.foreach(status => console.log(status));
ES6のPromiseより多機能ですし、何よりscalaから来た人は同じ感じで使えて嬉しいですね。
まとめ
TypeScriptってパターンマッチないとか高階型使えないとか色々制約あって辛みがありますね..。
でもJSで型安全なのは嬉しい限りです。∩( 'ヮ' 三 'ヮ' )∩