LoginSignup
0
1

More than 3 years have passed since last update.

もっと気持ち悪く switch を関数化したい

Last updated at Posted at 2020-04-22

元ネタ:4歳娘「パパ、constしか使わないで?」

メソッドチェインは関数合成なんだから、関数合成しまくったらどうにかなるだろうというゴリ押し実装。

  • 2020/4/23編集 : Elm の Either を意識した感を出すためにコードを整理
switchf.js
// 代数的データ型を関数に、
// パターンマッチを関数適用に見立てる宣言
const caseOf = match => adt => adt(match);

// Elm の Either を意識した何か
const Left = x => ({Left}) => Left(x);

const Right = x => ({Right}) => Right(x);

const andThen = Right => caseOf({
  Left,
  Right
});

const fromLeft = v => caseOf({
  Left: x => x,
  Right: _ => v
});

// switchの代替関数の作成用
const switchf = Right;

const caseIf = p => v => andThen(x => p(x) ? Left(v) : Right(x));

const caseEq = c => caseIf(x => x === c);

const caseDefault = fromLeft;

const compose = fs => fs.reduce((g, f) => x => f(g(x)), x => x);

// 使用例
const dayMessage = compose([
  switchf,
  caseEq(0)(() => "日曜日やで!ゆっくり休んでや!"),
  caseEq(1)(() => "月曜日やで!今週も頑張ろうな!"),
  caseEq(2)(() => "火曜日やで!"),
  caseEq(3)(() => "水曜日やで!"),
  caseEq(4)(() => "木曜日やで!"),
  caseEq(5)(() => "金曜日やで!もう少しで休みや!"),
  caseEq(6)(() => "土曜日やで!明日も休みやで!"),
  caseDefault(() => "曜日番号がおかしいで!"),
  lazy => lazy()
]);

// case の拡張例
const caseRange = (start, end) => caseIf(x => start <= x && x <= end);

const caseIn = arr => caseIf(x => arr.includes(x));

const dayMessage2 = compose([
  switchf,
  caseRange(1, 5)("平日やで"),
  caseIn([0, 6])("休日やで"),
  caseDefault("曜日番号がおかしいで!")
]);
0
1
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
0
1