Выражения сопоставления с образцом в Javascript - PullRequest
0 голосов
/ 30 ноября 2018

Я пробираюсь через функциональное программирование в JS.Недавно я начал использовать Daggy, чтобы выполнить простое сопоставление с образцом, но я не думаю, что полностью его получил.

Учитывая этот код:

  if(a === 1 && !b) {
   do(y)
  }

   if(b === 3 && c === 2) {
    do(z)
  }

  if (a) { 
    do(x) 
  }

Есть ли способ улучшить этоКогерсион на что-то похожее?

1007 *

Ответы [ 3 ]

0 голосов
/ 30 ноября 2018

Вы можете создать класс-оболочку для ваших данных, а затем использовать функции для проверки условий и выполнения действий в случае выполнения определенного условия.

Просто и легко, без каких-либо библиотек.

class typeWrap {

  constructor(obj) {
    this.var  =  obj;
    this.done = false;
  }

  when (condition, doFn) {

    if (!this.done && condition(this.var)) {
      this.done = true;
      doFn(this.var);
    }
    return this;
  }
}

const data = new typeWrap({
  b: 3, c : 9
});

data
  .when(
    d => d.a === 1 && !d.b,
    () => console.log('C1 => y')
  )
  .when(
    d => d.b === 3 && d.c !== 2,
    () => console.log('C2 => z')
  )
  .when(
    d => d.a,
    () => console.log('C3 => x')
  )
  .when(
    d => true,
    () => console.log('Last stop')
  );
0 голосов
/ 02 апреля 2019

Конечно, с Daggy вы можете определить Maybe

    const Maybe = daggy.taggedSum('Option', {
        Just: ['a'],
        Nothing: []
    })

, а затем определить для него функцию-прототип с именем alt, которая может в основном откатиться до переданного значения

    // alt :: Alt f => f a ~> f a -> f a
    Maybe.prototype.alt = function(o): Maybe<T> {
        return this.cata({
          Just: _ => this,
          Nothing: () => o
        })
      }

Так что сэто мы можем сделать некоторые сопоставления с образцом или аналогичные

    function match(comparator, res) {
      switch (comparator()) {
        case true: return Maybe.of(res)
        case false: return Maybe.Nothing
        default: return Maybe.Nothing
      }

    }

    MaybeF.Nothing
      .alt(match(() => a === 1 && !b, () => y))
      .alt(match(() => a, () => x))
      .alt(match(() => b === 3 && c === 2, () => z))
0 голосов
/ 30 ноября 2018

В JavaScript нет соответствия шаблону, о котором вы, вероятно, говорите.Существует активное предложение , чтобы добавить его с помощью case / when, вот пример из этого предложения:

const res = await fetch(jsonService)
case (res) {
  when {status: 200, headers: {'Content-Length': s}} -> {
    console.log(`size is ${s}`)
  }
  when {status: 404} -> {
    console.log('JSON not found')
  }
  when {status} if (status >= 400) -> {
    throw new RequestError(res)
  }
}

В настоящее время оно находится только на этапе 1 из процесс , тем не менее, может не продолжаться, может радикально измениться, прежде чем продолжить, и может потребоваться годы, чтобы проработать этапы и перейти на язык.Есть работа над плагином Babel .

Боюсь, мне не сразу понятно, как бы я применил его к вашему примеру, хотя, как мне кажется, нужен операнд для case.

Тем временем, серия if / else if может быть довольно краткой, если краткость - то, что вы ищете:

if (a === 1 && !b)           foo(y);
else if (a)                  foo(x);
else if (b === 3 && c === 2) foo(z);

или JavaScript switch необычно гибок (на самом деле это просто еще один способ написать if / else if):

switch (true) {
    case a === 1 && !b:      foo(y); break;
    case a:                  foo(x); break;
    case b === 3 && c === 2: foo(z); break;
}

(я не защищаю это, просто указываю, что это вариант.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...