From e9955e01d60773b96017acc1c6cd3dfae4dfb3e6 Mon Sep 17 00:00:00 2001
From: Aya Morisawa <AyaMorisawa4869@gmail.com>
Date: Wed, 6 Feb 2019 13:42:35 +0900
Subject: [PATCH] Introduce option type (#4150)

* Introduce option type

* Improve test naming
---
 src/prelude/maybe.ts  | 20 ++++++++++++++++++++
 test/prelude/maybe.ts | 28 ++++++++++++++++++++++++++++
 2 files changed, 48 insertions(+)
 create mode 100644 src/prelude/maybe.ts
 create mode 100644 test/prelude/maybe.ts

diff --git a/src/prelude/maybe.ts b/src/prelude/maybe.ts
new file mode 100644
index 0000000000..f9ac95c0b5
--- /dev/null
+++ b/src/prelude/maybe.ts
@@ -0,0 +1,20 @@
+export interface Maybe<T> {
+	isJust(): this is Just<T>;
+}
+
+export type Just<T> = Maybe<T> & {
+	get(): T
+};
+
+export function just<T>(value: T): Just<T> {
+	return {
+		isJust: () => true,
+		get: () => value
+	};
+}
+
+export function nothing<T>(): Maybe<T> {
+	return {
+		isJust: () => false,
+	};
+}
diff --git a/test/prelude/maybe.ts b/test/prelude/maybe.ts
new file mode 100644
index 0000000000..470eec220a
--- /dev/null
+++ b/test/prelude/maybe.ts
@@ -0,0 +1,28 @@
+/*
+ * Tests of Maybe
+ *
+ * How to run the tests:
+ * > mocha test/prelude/maybe.ts --require ts-node/register
+ *
+ * To specify test:
+ * > mocha test/prelude/maybe.ts --require ts-node/register -g 'test name'
+ */
+
+import * as assert from 'assert';
+import { just, nothing } from '../../src/prelude/maybe';
+
+describe('just', () => {
+	it('has a value', () => {
+		assert.deepStrictEqual(just(3).isJust(), true);
+	});
+
+	it('has the inverse called get', () => {
+		assert.deepStrictEqual(just(3).get(), 3);
+	});
+});
+
+describe('nothing', () => {
+	it('has no value', () => {
+		assert.deepStrictEqual(nothing().isJust(), false);
+	});
+});