Рамда: Помни и используй ценность - PullRequest
0 голосов
/ 17 июня 2020

Я пытаюсь "Рамдафи" сделать функцию бессмысленной. Вот как далеко я зашел:

const hasFetchedForFilterQueryString = state => {
  const filterQueryString = getFilterQueryString(state);
  return either(
    pipe(getPages, has(filterQueryString)),
    pipe(getNewlyLoadedUsers, has(filterQueryString)),
  )(state);
};

// or

const hasFetchedForFilterQueryString = state =>
  either(
    pipe(getPages, has(getFilterQueryString(state))),
    pipe(getNewlyLoadedUsers, has(getFilterQueryString(state))),
  )(state);

Интересно, есть ли способ написать еще больше без точек, так что без сохранения filterQueryString в переменной и необходимости вручную применять state?

1 Ответ

2 голосов
/ 17 июня 2020

Я обычно с комментарием Берги. Без очков не должно быть самоцелью. Я был очарован этим, когда начал писать Ramda, и в нем есть ряд функций, призванных упростить работу. Я их уже редко рекомендую. Я не думаю, что useWith или converge часто упрощают чтение или обслуживание функций.

Но есть функция lift, известный во всем мире FP, который здесь полезен. Я думаю о lift как о подъеме функции из области значений в область контейнеров этих значений. Таким образом lift (add) (Maybe(3), Maybe(5)) //=> Maybe(8). При использовании с функциями, которые передают наши значения, это может работать следующим образом:

lift ((a, b) => a + b) (
  n => n * 2, 
  n => n - 1
) (5) 
//=> (5 * 2) + (5 -1) //=> 14`.

И это именно то, что вы хотите делать со своей функцией. Итак, вот версия без точек на основе lift:

const hfffqs2 = either (
  lift (has) (getFilterQueryString, getPages),
  lift (has) (getFilterQueryString, getNewlyLoadedUsers)
)

Я считаю ее более читаемой, чем любая из приведенных выше версий.

Я думаю, что эта версия соперничает с простейшими не- Версия Ramda, которую я могу придумать для удобства чтения:

const hfffqs3 = state => {
  const query = getFilterQueryString(state);
  return query in getPages(state)
      || query in getNewlyLoadedUsers(state)
}

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

Если lift все еще не совсем понятно, промежуточный формат может выглядеть следующим образом:

const hfffqs1 = either (
  state => has(getFilterQueryString(state), getPages(state)),
  state => has(getFilterQueryString(state), getNewlyLoadedUsers(state))
)

Применяя getFilterQueryString и getState to lift (has) мы получаем эквивалент state => has(getFilterQueryString(state), getPages(state)), и аналогично со следующей строкой. Мы подняли функцию has из области строк и объектов в область функций , которые возвращают строки и объекты. Мы можем передать state этим двум функциям, чтобы получить строку и объект.


Вы можете увидеть их в действии в следующем фрагменте:

// Dummy implementations just for demo.  `state` is a small integer.
const getFilterQueryString = (state) => ['foo', 'bar', 'baz', 'qux', 'corge', 'grault'][state]
const getPages = (state) => [{foo: 1, bar: 2}, {foo: 1, corge: 2, grault: 3}, {baz: 1}, {foo: 1, grault: 2}, {corge: 1, baz: 2}, {bar: 1, qux: 2}][state]
const getNewlyLoadedUsers = (state) => [{baz: 1, qux: 2}, {corge: 1, grault: 2}, {foo: 1, corge: 2}, {baz: 1, qux: 2}, {foo: 1, qux: 2}, {bar: 1, corge: 2}][state]

const hasFetchedForFilterQueryString = state => {
  const filterQueryString = getFilterQueryString(state);
  return either(
    pipe(getPages, has(filterQueryString)),
    pipe(getNewlyLoadedUsers, has(filterQueryString)),
  )(state);
};

console .log ([0, 1, 2, 3, 4, 5].map(hasFetchedForFilterQueryString))

const hfffqs1 = either (
  state => has(getFilterQueryString(state), getPages(state)),
  state => has(getFilterQueryString(state), getNewlyLoadedUsers(state))
)

console .log ([0, 1, 2, 3, 4, 5].map(hfffqs1))

const hfffqs2 = either (
  lift (has) (getFilterQueryString, getPages),
  lift (has) (getFilterQueryString, getNewlyLoadedUsers)
)

console .log ([0, 1, 2, 3, 4, 5].map(hfffqs2))

const hfffqs3 = state => {
  const query = getFilterQueryString(state);
  return query in getPages(state)
      || query in getNewlyLoadedUsers(state)
}

console .log ([0, 1, 2, 3, 4, 5].map(hfffqs3))
.as-console-wrapper {min-height: 100% !important; top: 0}
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.27.0/ramda.js"></script>
<script> const {either, pipe, has, lift} = R                         </script>
...