Возможна ли цепочка Может быть, в случае 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
.
У меня два вопроса:
- Почему
Maybe.map
не обрабатывает null / undefined? - Как переписать
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'
])