Возможна ли цепочка Может быть, в случае null/undefined?

Есть заданная функция, которая фиксирована и не может быть изменена:

const validate = v => v === "fred" ? "Y" : undefined

Теперь, поскольку я хотел бы работать и избежать нулевых проверок, я решил использовать Maybe (ramda-fantasy) для функции проверки:

const vv = val => Maybe(val).map(v=> validate(v)).getOrElse("N")

vv должен вернуться Y если он называется с "fred" иначе N.

  • vv(null) возвращается N -> ОК
  • vv("fred") возвращается Y -> ОК
  • vv("ding") возвращается undefined -> неправильно, ожидалось N

Проблема в том, что Maybe.map всегда возвращается Just, этого я не понимаю (потому что я только изучаю это). Для меня было бы полезно, если бы эта функция вела себя аналогично Maybe(val) что возвращается None или же Just.

У меня два вопроса:

  1. Почему Maybe.map не обрабатывает null / undefined?
  2. Как переписать vv что он вернет ожидаемые значения во всех трех случаях?

РЕДАКТИРОВАТЬ: Я хотел бы объяснить, почему не следует изменять валидацию: это просто простой пример функции, поступающей из внешней библиотеки. Я хотел увидеть, насколько легко / сложно интегрировать такие библиотеки в функциональное программирование. Таким образом, речь идет не о строковых операциях, а только о потоковой передаче значений, когда в какой-то момент она принимает значение null.

РЕДАКТИРОВАТЬ2:

Это решает мою проблему:

Either.ofNullable = Either.prototype.ofNullable = function (value) {
    return value == null ? Either.Left("is null") : Either.Right(value);
};

1 ответ

Решение

Примечание: Ramda Fantasy больше не поддерживается. Команда рекомендует использовать другие реализации этих концепций.


Но мы все еще можем ответить на этот вопрос, поскольку он, вероятно, будет верным для любого разумного Maybe реализация

По сути, Maybe создан для работы не так. Идея в том, что у вас может быть абсолютно любое значение Just. Это включает в себя ценности null и undefined.

Ramda добавил удобный конструктор, Maybe (val), который превращается в Just (val) если val не является нулевым значением, и в Nothing ()если это. Но это не значит, что вы не можете создать Just (null). Основной прием строительства - использование статических Maybe .of. И вы можете отметить, что

Maybe (null)    //=> Nothing ()
Maybe.of (null) //=> Just (null)

Так что мы, вероятно, не собираемся заставлять эту технику работать. Мы не могли просто map такой существующий validate над нашим Maybeи ожидайте, что это сработает. Однако мы могли бы работать с такой версией:

const validate = v => v === "fred" ? Just ("Y") : Nothing ()

Здесь у нас все еще есть одна проблема. Maybe ('fred') .map (validate) дает Just (Just ('Y')). У нас есть дополнительное гнездование. Но это именно то, что chainдля. Он убирает такой дополнительный уровень, чтобы Maybe ('fred') .chain (validate) дает Just ('Y'). Затем мы можем использовать его так:

const validate = v => v === "fred" ? Just ("Y") : Nothing ()
const vv = val => Maybe (val) .chain (validate) .getOrElse ('N')

console .log ([
  vv (null),   // 'N'
  vv ('fred'), // 'Y' 
  vv ('ding')  // 'N'
])
Другие вопросы по тегам