#ramda.js #ramda-fantasy
#ramda.js #рамда-фантазия
Вопрос:
Существует заданная функция, которая является фиксированной и не должна быть изменена:
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
-> OKvv("fred")
возвращаетY
-> OKvv("ding")
возвращаетundefined
-> неверно, ожидаемоN
Проблема в том, что Maybe.map
всегда возвращается Just
, что я не понимаю (потому что я только учусь этому). Для меня было бы полезно, если бы эта функция вела себя аналогично тому Maybe(val)
, что возвращает None
or Just
.
У меня два вопроса:
Maybe.map
Почему не обрабатывает null / undefined?- Как переписать
vv
, чтобы он возвращал ожидаемые значения во всех трех случаях?
РЕДАКТИРОВАТЬ: я хотел бы объяснить, почему validate не следует изменять: это просто простой пример функции, поступающей из внешней библиотеки. Я хотел посмотреть, насколько легко / сложно интегрировать такие библиотеки в функциональное программирование. Речь идет не о строковых операциях, а только о потоковых значениях, когда в какой-то момент оно принимает значение null.
ПРАВКА2:
Это решает мою проблему:
Either.ofNullable = Either.prototype.ofNullable = function (value) {
return value == null ? Either.Left("is null") : Either.Right(value);
};
ПРАВКА3:
Я реализовал свой собственный либо с отсутствующей функциональностью: https://github.com/maciejmiklas/functional-ts/blob/main/src/either.ts
Ответ №1:
Примечание: Фантазия Ramda больше не поддерживается. Команда рекомендует вам использовать другие реализации этих концепций.
Но мы все еще можем ответить на этот вопрос, поскольку это, вероятно, верно для любой разумной Maybe
реализации
В принципе, это не то, как Maybe предназначен для работы. Идея в том, что вы можете просто удерживать абсолютно любое значение. Это включает в себя значения null
и undefined
.
Рамда добавил удобный конструктор, 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'
])
Комментарии:
1. OP просил соблюдать
validate
такт.val => Maybe(validate(val)).getOrElse("N")
Работает ли? Хороший пример для Maybe.2. @Thankyou: Хотя да, это сработало бы, кажется, нет причин использовать
Maybe
для этого. Просто(v, r = validate2(v)) => r == 'Y' ? 'Y' : 'N'
было бы хорошо. Обертывание чего-либо в Maybe только для того, чтобы развернуть его в том же выражении, не добавляет ничего полезного. Я полагаю, я должен был также предложить что-то вроде(val) => Maybe(val).map(validate).getOrElse('N') || 'N'
, но я предположил, что это очевидно, и на самом деле не помогает узнатьMaybe
.3. @Thankyou: Или, я полагаю, мы могли бы стать еще более странными и использовать что-то вроде
(val) => Maybe(Maybe(val).map(validate).getOrElse('N')).getOrElse('N')
. Но я бы не был доволен этим.4. Мое первоначальное понимание заключалось в том, что это
validate
была импортированная функция, и OP хотел перенести ее вMaybe
домен5. @Thankyou: Да, я понимаю, но я предполагал, что цель состояла в том, чтобы использовать его как-то вместе с.
Maybe(val)
Простое введение aMaybe
в контекстеString -> String
функции не имеет для меня особого смысла; есть много способов сделать это лучше. Но я не думаю, что есть хороший способ сделать то, что, по моему мнению, хочет OP, то есть объединитьJust(String) | Nothing()
сString -> String | Undefined
to getString ('Y'|'N')
.undefined
(возможно, к сожалению) является значением на языке и может содержаться в aJust
. Но возможно, что я совершенно неправильно понимаю.