🍛

カリー化,高階関数,ファクトリ関数,依存性の逆転

に公開

依存性の逆転を関数型で書く

これを読み解く。
難しかったら次の カリー化と高階関数へ 。

type QueryFn = (sql: string) => Promise<any>;

const makeGetUser =
	(query: QueryFn) =>
	async (id: number): Promise<any> => {
		const sql = `SELECT * FROM users WHERE id = ${id}`;
		return query(sql);
	};

// ファクトリ関数
function createUserService(query: QueryFn) {
	const getUser = makeGetUser(query);
	return {
		getUser,
	};
}

// MySQL 実装
const queryMySql: QueryFn = async (sql) => {
	console.log(`→ MySQL 実行: ${sql}`);
	// MySQL ドライバ呼び出し…
	return { id: 1, name: "Taro" };
};

// PostgreSQL 実装(新しく追加したい DB)
const queryPostgres: QueryFn = async (sql) => {
	console.log(`→ PostgreSQL 実行: ${sql}`);
	// PostgreSQL ドライバ呼び出し…
	return { id: 2, name: "Hanako" };
};

(async () => {
	const mysqlService = createUserService(queryMySql);
	const mysqlUser = await mysqlService.getUser(1);
	console.info(mysqlUser);

	const pgService = createUserService(queryPostgres);
	const pgUser = await pgService.getUser(2);
	console.info(pgUser);
})();
→ MySQL 実行: SELECT * FROM users WHERE id = 1
{ id: 1, name: 'Taro' }
→ PostgreSQL 実行: SELECT * FROM users WHERE id = 2
{ id: 2, name: 'Hanako' }

カリー化と高階関数

難しかったら次の カリー化へ 。

function add(a: number, b: number): number {
  return a + b;
}

// カリー化された高階関数
function curry2<A, B, R>(
  fn: (a: A, b: B) => R
): (a: A) => (b: B) => R {
  return (a: A) => (b: B) => fn(a, b);
}

const curriedAdd = curry2(add);
const add5 = curriedAdd(5);
console.log(add5(3));

カリー化

const foo = (x: number) => (y: number) => x + y;
const bar = foo(1);

console.info(`bar(2): ${bar(2)}`);
console.info(`foo(1)(2): ${foo(1)(2)}`);
bar(2): 3
foo(1)(2): 3

さらに詳しく・・・

const gx = (x: number) => {
	console.log("outer got", x);
	return (y: number) => {
		console.log("inner got", y);
		return x + y;
	};
};

// これを簡潔に書くと
const gy = (x: number) => (y: number) => x + y;

console.info(`gx(1)(2): ${gx(1)(2)}`);
console.info(`gy(1)(2): ${gy(1)(2)}`);
outer got 1
inner got 2
gx(1)(2): 3
gy(1)(2): 3

関数型への動機

https://alexanderdanilov.dev/en/articles/oop?ref=dailydev

Discussion