Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
  • Jan 31 2019 22:17
    CrossEye commented #2779
  • Jan 31 2019 21:04
    ArturAralin commented #2779
  • Jan 31 2019 20:08
    CrossEye commented #2779
  • Jan 31 2019 18:56
    buzzdecafe commented #2631
  • Jan 31 2019 18:09
    ArturAralin commented #2779
  • Jan 31 2019 16:18
    CrossEye commented #2779
  • Jan 31 2019 16:10
    CrossEye commented #2631
  • Jan 31 2019 16:06
    CrossEye commented #2777
  • Jan 31 2019 14:44
    ArturAralin opened #2779
  • Jan 31 2019 07:39
    inferusvv commented #2631
  • Jan 31 2019 03:07
    sespinozj commented #2771
  • Jan 31 2019 02:33
    machad0 commented #2771
  • Jan 31 2019 02:26
    JeffreyChan commented #2777
  • Jan 30 2019 14:30
    CrossEye closed #2777
  • Jan 30 2019 12:13
    vanyadymousky updated the wiki
  • Jan 30 2019 01:42
    JeffreyChan commented #2777
  • Jan 29 2019 21:06
    vanyadymousky updated the wiki
  • Jan 29 2019 16:28
    CrossEye commented #2777
  • Jan 29 2019 15:50
    mbostock commented #2772
  • Jan 29 2019 15:48
    CrossEye commented #2772
Brad Compton (he/him)
@Bradcomp
I think allPass is what you want. it allows you to apply a series of predicates to a value and fails if any of the predicates fail
all applies a single predicate to a list of values.
ed@sharpertool.com
@kutenai
Okay, slight mod, but this works: R.allPass(R.map(R.has, properties))(obj)
The first one is great though, it gives me a re-usable solution: const hasRequiredKeys = R.allPass(R.map(R.has, required_keys))
and hen just do hasRequiredKeys(obj)
Well, thanks a lot @Bradcomp
Brad Compton (he/him)
@Bradcomp
Happy to help! :bowtie:
MrB
@Branavan-
Hi, I'm wondering if Ramda is for use under MIT (as it states on the GitHub page) or if it's CC-BY-NC-SA-3.0 as it states on Ramda's website.
I have a feeling that the package is for use under MIT and the content of the website (like the logos and stuff) are covered under CC-BY-NC-SA-3.0. Would anyone be able to confirm?
Brad Compton (he/him)
@Bradcomp
That's correct. The CC license is actually for the logo.
MrB
@Branavan-
Thanks for confirming @Bradcomp !
Andreas Herd
@mendrik
hmm how do I find the index of the largest integer in a list?
yasenfire
@yasenfire
When you have a list of values and you need to turn this list into one value, it's reduce. You need to, well, reduce the list to this value. The thing is functional reduce of ramda only passes accumulator and next value, not index of the element processed. So you also need addIndex to get a reduce function that passes both index and value
26 replies
Azat S.
@azat-io
image.png
10 replies
Hi! What’s wrong in my TypeScript code?
import { compose, fromPairs, map, props } from "ramda";

type Category = {
    id: number;
    name: string;
};

const data: Category[] = [
    {
        id: 1,
        name: "foo"
    },
    {
        id: 2,
        name: "bar"
    }
];

const idNames = compose(
    fromPairs,
    map(props(["id", "name"]))
);

const obj = idNames(data);

console.log("obj", obj);
Argument of type 'unknown[]' is not assignable to parameter of type '(x0: unknown, x1: unknown, x2: unknown) => KeyValuePair<number, unknown>[]'.
      Type 'unknown[]' provides no match for the signature '(x0: unknown, x1: unknown, x2: unknown): KeyValuePair<number, unknown>[]'.

21     map(props(["id", "name"]))
Azat S.
@azat-io
Marcelo Olivas
@mfolivas
FP newbbie, I want to create an error handler. I know how to do it in OOP, but I just saw the talk about Railway Oriented Programming and it sounds pretty compelling. How does someone implements this practice with Ramda?
wangzengdi
@adispring
@mfolivas you can use composeWith to do Railway Oriented Programming
amir
@amirbr
Hello I'm trying to filter array by multi function that filter by different property. and in then end to use pipe
but I missing something there. someone can help, please.
example:
https://ramdajs.com/repl/?v=0.27.0#?%0Aconst%20publicationlist%20%3D%20%5B%0A%20%20%7B%0A%20%20%20%20id%3A%20%271%27%2C%0A%20%20%20%20provider%3A%20%27A%27%2C%0A%20%20%7D%2C%0A%20%20%20%20%7B%0A%20%20%20%20id%3A%20%272%27%2C%0A%20%20%20%20provider%3A%20%27B%27%2C%0A%20%20%7D%2C%0A%20%20%20%20%7B%0A%20%20%20%20id%3A%20%273%27%2C%0A%20%20%20%20provider%3A%20%27C%27%2C%0A%20%20%7D%2C%0A%20%20%20%20%7B%0A%20%20%20%20id%3A%20%274%27%2C%0A%20%20%20%20provider%3A%20%27A%27%2C%0A%20%20%7D%2C%0A%20%20%20%20%7B%0A%20%20%20%20id%3A%20%275%27%2C%0A%20%20%20%20provider%3A%20%27A%27%2C%0A%20%20%7D%2C%0A%5D%20%0A%0Aconst%20filterByProvider%20%3D%20R.curry%28%28providerList%2C%20publications%29%20%3D%3E%0A%20%20R.filter%28item%20%3D%3E%20%28providerList.length%20%3E%200%29%20%3F%20providerList.includes%28item.provider%29%20%3A%20true%20%2C%20publications%29%29%0A%0Aconst%20filterById%20%3D%20R.curry%28%28idList%2C%20publications%29%20%3D%3E%0A%20%20R.filter%28item%20%3D%3E%20%28idList.length%20%3E%200%29%20%3F%20idList.includes%28item.id%29%20%3A%20true%20%2C%20publications%29%29%0A%0A%0Aconst%20x%20%3D%20%28providerList%2C%20idList%2C%20publications%29%20%3D%3E%20R.pipe%28%0A%20%20filterByProvider%28providerList%2C%20publications%29%2C%0A%20%20filterById%28idList%2C%20publications%29%0A%29%0A%0Aconst%20result%20%3D%20x%28%5B%27A%27%2C%20%27B%27%5D%2C%20%5B%273%27%5D%2C%20publicationlist%29%0A%0Aconsole.log%28result%2C%20%27result%27%29%0A%0A%0A%0A%0A%0A%0A%0A
wangzengdi
@adispring
@amirbr
https://codepen.io/adispring/pen/BazGNdE?editors=0010 .
R.pipe should compose small functions into a bigger function. In your code, R.pipe composes functions' results, which results in the wrong behavior.
Marcelo Olivas
@mfolivas
@adispring thanks! Is there an example? Also, I could imagine that you could the same with pipeWith.
amir
@amirbr
Yes, I see what you mean.
Thank you!! @adispring
wangzengdi
@adispring
@mfolivas Yes, R.pipeWith do the same thing in the reverse way. There is an example in ramda's document: https://ramdajs.com/docs/#composeWith. composeWhileNotNil could process data continuously while the data is not nil, otherwise, it will return undefined/null in the shortcut way.
wangzengdi
@adispring
Like composeWhileNotNil, we can write a function to handle Error:
const composeWhileNotError = R.composeWith((f, res) => R.is(Error, res) ? res : f(res));
Marcelo Olivas
@mfolivas
oh nice!
thanks @adispring
Azat S.
@azat-io

Hello! How can I pass second argument in Ramda to compose?

I need to print ’number’ in console here:

compose(
  tap(flip((x) => {
    console.log('x', typeof x)
  }))
)('string', 123)
Giuseppe Mandato
@hitmands
Hi @azat-io , the issue is more that tap is a unary function.
R.compose(
  R.flip(R.divide)
)(10, 2); // 0.2
Matt Diamond
@mattdiamond
I don't have a question, just wanted to share something I put together recently with the help of Ramda: https://observablehq.com/@mattdiamond/the-select-monad
it was especially satisfying to see R.sequence working perfectly with the Select monad
though I think the docs for ap are slightly inaccurate, as they state that it will dispatch to the .ap method of the 2nd argument, whereas in reality it dispatches to the .ap method of the first argument (which makes more sense to me anyway)
if present it will dispatch to the fantasy-land/ap method of the second argument, though, which might be what the docs mean
Brad Compton (he/him)
@Bradcomp
I am excited to dig into this!
Matt Diamond
@mattdiamond
@Bradcomp glad to hear! lmk if you have any questions, though it's pretty straightforward (I think)
I don't know if maybe I typed snapshot wrong, or if you really have to so verbose as to take all the arguments and pass them through just to type them.
const tag = snapshot (x => _ => x)
// vs
const tag = <X, Y> (boxX: Box<X>) => (boxY: Box<Y>) => snapshot ((x: X) => _ => x) (boxX) (boxY)
Johnny Hauser
@m59peacemaker
I got it. I had tried this and put the generic in the wrong spot :/
const tag = snapshot (<X> (x: X) => _ => x)
Tom
@tofo_gitlab
Still sad to see Ramda at version 0. Could this be the end of Ramda?
Marcelo Olivas
@mfolivas

Newbie here! Wondering how I would apply fp along with error handling. There is this notion of Railway Oriented Programming, but it does seem like there is a need to have some monads (Maybe and Join??) that are not available on Rambda and I should look into Santuary to really leverage Railway Oriented. Here's my question:

const hasNoCitationNumber = citation => R.isNil(R.prop('citationNumber', citation))
const citationValidation = citation => {
  if (hasNoCitationNumber(citation)) {
    throw new TypeError('Citation number is required') 
  }
  return citation
}

const calculateAmount = citation => {
  const balance = R.add(R.prop('amount', citation), R.prop('fee', citation))
  return {
    ...citation,
    balance
  }
}
const citationService = R.pipe(citationValidation, calculateAmount)
const citation = {citationNumber: '12345', amount: 100, fee: 10}
//citationService(citation)
const pipeWhileNotError = R.pipeWith((f, res) => R.is(TypeError) ? res : f(res))
const citationBuilder = pipeWhileNotError([citationValidation, calculateAmount])
//citationBuilder(citation)
citationBuilder({})

is this right? Is this truly error handling in fp?

Geovanny Junio
@geovannyjs
@tofo_gitlab Would not it just be the version scheme that Ramda follows? Not being above 0 in the version schemes does not necessarily means that a lib is dying, I hope.
Geovanny Junio
@geovannyjs
@mfolivas Newbie here too. Overall your solution seems to trully handle the error in a fp way. If we talk specifically about the citationValidation we could question the fact of it returning an Object or an Error (Object | Error) and it is not explicit in the function signature since javascript has not types. If you would like to be very fp purist, maybe you could encapsulate the return value in a Either like monad.
Marcelo Olivas
@mfolivas
@geovannyjs , thanks! That's why many have suggest to look at other lib like Santuary since they have the Either monad.
Brad Compton (he/him)
@Bradcomp
const citationValidation = citation => {
  if (hasNoCitationNumber(citation)) {
    throw new TypeError('Citation number is required') 
  }
  return citation
}

We should separate out the specific validation we are doing from the way that we are validating. In this case, the specific validation is hasNoCitationNumber, and citationValidation just wraps that.

The way you are validating in this case is by throwing an error. Let's pull that out:

const validate = curry((predicate, message, object) => {
  if (!predicate(object)) {
    throw new TypeError(message);
  }
  return object;
}
const citationValidation = validate(hasNoCitationNumber, 'Citation number is required');

Now we can easily construct new validators that will do the same thing as our existing one. We can also swap out the error handling (for instance to use Either):

const validate = curry((predicate, message, object) => predicate(object) ? Right(object) : Left(message));

All the rest of the code can stay the same.

Also, I don't know if the original code will do the right thing. Throwing an error won't end up in the function in pipeWith. It will still short circuit the rest of the pipe, but I think you'd want to return the error in citationValidation instead of throwing it...

Would not it just be the version scheme that Ramda follows? Not being above 0 in the version schemes does not necessarily means that a lib is dying, I hope.

Not dying, but we really need to get on a more consistent release schedule. We're working on that!

Geovanny Junio
@geovannyjs
I just arrived here and even still need to read the docs, and github stuff... but is there some plan to provide some effects like Maybe, Either, Validated, etc...?
Brad Compton (he/him)
@Bradcomp

Ramda doesn't have those and probably won't have them in the future. It's more focused on utilities that work with typical JS entities, and it dispatches so that you can use custom objects.

A lot of Ramda users also use Sanctuary, however it's a lot more strict as it has a runtime type checker. You can use the data types without the type checking by either turning type checking off or else importing the individual projects (i.e. sanctuary-either). There are a few other projects out there I have used for the data types that I like: Crocks has a lot of good ADTs and utilities. I used to use Folktale but a while ago they did a huge update and I lost track of the project after that.

Geovanny Junio
@geovannyjs
@Bradcomp thank you :thumbsup:
Marcelo Olivas
@mfolivas
thanks @Bradcomp !