const sumEq = curry((n, list) => pipe(sum, equals(n))(list));
How can I validate that a request is a JSON object? I did something like this:
const getTags = (request) => {
if (isEmpty(request) || !is(Object, request)) {
throw new TypeError(
'The #request is required and needs to be an JSON object'
)
}
But then I realized that is(Object, [])
returns true
export const isNullOrEmpty = (request) => isNil(request) || isEmpty(request)
/**
* Check if the incoming request is either empty, null, or undefined and if it
* is not a JSON object
*
* @param {*} request - incoming request
* @returns {boolean} true when the request is either null, undefined, or empty,
* and it is not a JSON object
*/
export const isEmptyOrNotJSONObject = (request) =>
isNullOrEmpty(request) || request.constructor !== Object
Hi there!
Got a function combination problem and was wondering if Ramda could help me write it in a point-free style.
Basically, I have 2 functions both which take the same input. One function returns a Promise which resolves to a string and the second function returns a string. I want to join the results of the two functions using path.join
.
I.e, non point-free:
const fn = obj => getString1(obj).then(s1 => path.join(s1, getString2(obj))
Using ramda's join
with a forward-slash instead of path.join
is acceptable. Is there a point-free way of combining these functions?
I thought perhaps lift
could help but I figure it out with the promise-returning function.
pipeWith(f, g, x)
i can write pipeWith(x, f, g)
i don't think so. maybe you can use R.reverse
for the arguments
const pipeWhileNotNil = R.pipeWith((f, res) => R.isNil(res) ? res : f(res));
const f = pipeWhileNotNil(R.reverse[Math.pow, R.negate, R.inc])
Note this code is only for demo, prob it will not work @theqp
:point_up: Edit: i don't think so. maybe you can use R.reverse
for the arguments
const pipeWhileNotNil = R.pipeWith((f, res) => R.isNil(res) ? res : f(res));
const f = pipeWhileNotNil(R.reverse[Math.pow, R.negate, R.inc])
Note this code is only for demo, prob it will not work but you got the idea 🙂 @theqp
const tagger = curry((tag, text, template) => pipe(
when(
includes(tag),
pipe(
replace(tag, text),
tagger(tag, text)
)
)
)(template))
const applyTags = (tags, template) =>
pipe(
toPairs,
map(over(lensIndex(0), s => `{${s}}`)),
reduce(pipe(append, apply(tagger)), template)
)(tags)
const tags = {
test: 'tasty test',
cheese: 'amazing smoked gouda'
}
const template = 'this is a {test}. I love {cheese}.'
applyTags(tags, template) // "this is a tasty test. I love amazing smoked gouda."
const includedIn: <T>(list: T[]) => (item: T) => boolean =
list => item => includes(item)(list)
Hi, I'm new to functional programming and Ramda. How might you improve these functions? Can any be made pointfree? Thank you!
//
// elementAfter(el, list) returns the element after el in the list
// (wapping to the beginning if needed)
// how would you improve these functions? can any be made pointfree?
//
const indexAfter = (index, list) => mathMod(inc(index), length(list))
const indexAfterElement = (el, list) => indexAfter(indexOf(el, list), list)
const elementAfter = (el, list) => nth(indexAfterElement(el, list), list)
elementAfter('c', ['a', 'b', 'c']) // 'a'
Ramda REPL: https://tinyurl.com/yhwpgykj
// This fails cause "reduce: list must be array or iterable"
R.transduce(mapfilterComp, R.groupBy(R.prop('programId')), {}, settings)
// This is a function that returns a function with it's arguments re-arranged.
// I'm not sure how useful it is, i just wanted to make one.
// You specify the new argument order with an integer, with each digit from 1-9
// symbolising the original order.
// for example, to switch the order of a binary function like divide, we use 21
// we're counting from 1.
// swap(21, divide)(4,2) //--> 0.5
//
// More complex now
// swap(42133, foo)(these, are, some, args, wow)
// equiv. to: foo(args, are, these, some, some)
// Note you can repeat numbers to pass to the same value multiple times.
// The function applies curryN to the result based on how many digits there are,
// giving you partial application, of sorts.
const swap = curry((n, f) => {
const argMap = Array.from(n.toString()).map(x => parseInt(x) - 1)
return curryN(argMap.length, (...args) =>
f(
...addIndex(map)((a, i) => {
const newPos = argMap.indexOf(i)
return newPos !== -1 ? args[newPos] : a
}, args)
)
)
})
Hi, I have the following code that is returning true when it should return false:
const isNotEmpty = R.complement(R.isEmpty)
const isNotNil = R.complement(R.isNil)
const isNotEmptyFeed = R.and(R.pathSatisfies(isNotEmpty, ['data', 'children']), isNotNil)
isNotEmptyFeed({
subreddit: 'abruptchaos',
feedCategory: 'posts_Default',
feedUrl: 'https://www.reddit.com/r/abruptchaos/.json?limit=100&count=100&after=null',
data: { children: [] },
})
https://tinyurl.com/ydmqb9ls
Can anyone tell me where I've gone wrong here? data.children
is empty, so that should be false right?
Hi there, does the following combinator have a name? Or, on the other hand, how we usually deal this pattern instead of composing with the combinator? For example:
// ???
const combinator = R.curry((f, g, x, y) => f ( g(x) ) ( y ) )
// findById :: ((Record K V -> Boolean) -> [Record K V] -> Maybe Record K V) -> (V -> Record K V -> Boolean) -> V -> [Record K V] -> Maybe Record K V
const findById = combinator(R.find, R.propEq("id"))
findById(1)([{id: 1}])
//> {id: 1}
I know the combinator can be derived from the following 2 functions, where g
is identity
.
https://github.com/ramda/ramda/blob/ed191e6a476330e37db259a5c2d04bfba0b2d63d/source/useWith.js#L21
https://github.com/fantasyland/fantasy-birds/blob/6f37c6e7daf31f1c31860f0f307555f4c7922ec2/src/dovekie.js#L4
But, is there a more elegant way to deal with it? Any suggestions or perspectives are welcome.
@zxol Thank you, it is exactly the same beta-reduction as mine. And then my following question comes up:
If the function is variadic, then I need a I**
combinator to achieve the same functionality, does it make sense?
const idstarstar = R.curry((f, x, y) => f(x)(y))
// right associative
// findById :: (Pred -> [a] -> Maybe a) -> (v -> Pred) -> v -> ([a] -> Maybe a)
const findById = R.compose(R.find, R.propEq("id"))
idstarstar(findById)(1, [{id: 1}])
https://github.com/fantasyland/fantasy-birds/blob/6f37c6e7daf31f1c31860f0f307555f4c7922ec2/src/idstarstar.js#L4
I think the problem is that f(g(x))
returns another function, so I can not give 2 arguments at once and apply to v -> ([a] -> Maybe a)
.
Is there a more elegant way to deal with it? Any suggestions or perspectives are welcome.