2
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

JavaScriptでEither

Last updated at Posted at 2018-03-20

JavaScript + 関数型プログラミングメモ

folktale v2においては Either は Result という名前になっている。Leftは、 Result.Error, Right は Result.Ok という名前になっている。まずは Either を作る。

const assert = require('assert');
const Result = require('folktale/result');
// create either
{
  const rights = [
    Result.Ok(1),
    Result.Ok({ one: 1 }),
  ];
  rights.forEach((d) => {
    assert(d instanceof Result.Ok);
  });
  const lefts = [
    Result.Error(1),
    Result.Error({ one: 1 }),
  ];
  lefts.forEach((d) => {
    assert(d instanceof Result.Error);
  });
}

例外throw型の関数は、 Result.try() を使って関数の返り値or送出された例外をEitherにすることができる。Eitherは mapとmapErrorで、それぞれの成功状態を変更せずに、値を変更できる。matchWith でパターンマッチング、条件分岐ができる。mergeを使うと、成功状態を問わず値を取り出すことが出来る。Eitherが Result.OkResult.Error かは、hasInstanceOf で判別することができる。

// work with either
{
  const f = (arg) => {
    if (arg) return arg;
    throw Error('falsy');
  };
  assert.deepEqual(
    Result.Ok('HELLO!'),
    Result.try(() => f('hello'))
      .map(str => str.toUpperCase()).map(str => str.concat('!')),
  );
  assert.deepEqual(
    Result.Error(Error('falsy')),
    Result.try(f)
      .map(str => str.toUpperCase()).map(str => str.concat('!')),
  );
  assert(Result.Ok.hasInstance(Result.Ok('hello')));
  assert(Result.Error.hasInstance(Result.Error('hello')));
  const getName = (id) => {
    if (id === 1) return 'alice';
    throw Error('no such user!');
  };
  Result.try(() => getName(1)).matchWith({
    Ok: ({ value }) => { assert.equal('alice', value); },
    Error: () => { throw Error('cannot reach here'); },
  });
  Result.try(() => getName(2)).matchWith({
    Ok: () => { throw Error('cannot reach here'); },
    Error: ({ value }) => { assert.deepEqual(Error('no such user!'), value); },
  });
  assert.equal(
    'guest',
    Result.try(() => getName()).mapError(() => 'guest').merge(),
  );
  assert.equal(
    'alice',
    Result.try(() => getName(1)).mapError(() => 'guest').merge(),
  );
}
2
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?