These are chat archives for ramda/ramda

19th
Apr 2017
Cody
@Condell
Apr 19 2017 00:04
Possibly? Haha, sorry I'm not even really sure, but thank you for your response! I'm just a little confused about property based testing like this because I don't really understand how to "pull the value out" of the monad, for just the test itself if that makes sense?
i mean i know how to get to the value itself in my "real" code, but do i need to pull the value out for the test?
when i look for examples of property based testing, all the functions themselves return a "built-in(idk if that's the right term here)" data type like Number, or String, and never an Either or anything.
Tre'
@wayneseymour
Apr 19 2017 00:37
Hello! Guys and gals, whats the best package for using ramda in typescript?
Jason Shin
@JasonShin
Apr 19 2017 00:57
@mrtnbroder thx
Ian Hofmann-Hicks
@evilsoft
Apr 19 2017 02:21
@Condell really it all depends on the thing you are working with. for instance, I have an Async container that is like fluture or data.task. So because I have a hook with the fork function, I can set up the tests like: https://github.com/evilsoft/crocks/blob/master/crocks/Async.spec.js#L209
or I can set up spys and see what was passed into the function: https://github.com/evilsoft/crocks/blob/master/crocks/Async.spec.js#L585
Now for my Identity I can pull it out with a value function. so that is easy to test: https://github.com/evilsoft/crocks/blob/master/crocks/Identity.spec.js#L139
But when we get into Sum Types like Maybe, Either, Result, etc. then I have an either function that "folds" the value out through 2 functions like this: https://github.com/evilsoft/crocks/blob/master/crocks/Either.spec.js#L244
Ian Hofmann-Hicks
@evilsoft
Apr 19 2017 02:27
or option for the Maybe type, to provide a default value if the Maybe is Nothing: https://github.com/evilsoft/crocks/blob/master/crocks/Maybe.spec.js#L293
Cody
@Condell
Apr 19 2017 02:27
@evilsoft This is gonna sound SO stupid... But I think the problem I was stuck on was "where do the functions I actually write come into play when using jsverify to test?" because none of the articles i read really explained that. They all just said "the test takes a function that will return true if the provided inputs work." And it finally hit me, you use the function you write to "do something" INSIDE of that test function. Is that right? Sorry I'm just starting out with this and just finished Prof Frisbys Guide.
Ian Hofmann-Hicks
@evilsoft
Apr 19 2017 02:29
never used jsverify. give me a second to get up to speed
ohhh. this is going to take a minute. will hit you up. This is interesting!!
Cody
@Condell
Apr 19 2017 02:31
ok, no problem. thank you so much!!! What do you usually use? I see you use Tape, so you dont really use property based testing?
Ian Hofmann-Hicks
@evilsoft
Apr 19 2017 02:31
nope, but that could all change in about an hour if this is saying what I think it is saying
Cody
@Condell
Apr 19 2017 02:32
haha, okay then. Maybe we'll be on the same page, just starting with property based testing, and ill have someone that actually knows what they are doing to help.
Ian Hofmann-Hicks
@evilsoft
Apr 19 2017 02:34
:sweet_potato:
Brad Compton (he/him)
@Bradcomp
Apr 19 2017 02:37
There are a number of PBTs in Ramdas test base
Just posting the links for some examples / ideas :-D
Cody
@Condell
Apr 19 2017 02:41
@Bradcomp ah thank you! I'm not sure why it never occurred to me to check Ramda's tests haha.
is there any particular reason you guys didnt use mocha or anything like that? just to minimize overall code?
Brad Compton (he/him)
@Bradcomp
Apr 19 2017 02:43
They are using mocha ;)
Cody
@Condell
Apr 19 2017 02:43
or chai, sorry haha
just wondering how I should set my tests up and stuff, i looked for a "best practices" sort of thing but couldnt find anything.
or wait assert is being used, jeez lol
i need a break
Brad Compton (he/him)
@Bradcomp
Apr 19 2017 02:57
There are a lot of variations on how to set up the tests.
Cody
@Condell
Apr 19 2017 03:04
this is gonna sound stupid, but I'm guessing there are 2 describe blocks for each function, 1st for unit tests and the other for property based?
Brad Compton (he/him)
@Bradcomp
Apr 19 2017 03:09
Yeah
That's not necessary though, it's just how it is organized
Cody
@Condell
Apr 19 2017 03:11
Ok, gotcha, thanks! I think that's what was confusing me too. Is it normal, or a best practice or anything to have one function per file as well?
actually nevermind, probably not . only for ramda as it is a library
Robert Mennell
@skatcat31
Apr 19 2017 05:58
@Condell it would depend on your testing how many things you test in one file. Remember to Code to your tests, don't test your code.
honestly though even with short single file libraries it's often considered good practice to piece wise your tests into multiple files, and run them through a suite file so that you can update tests as you update code without having to trim through a huge file. This allows you some nifty tricks... Like putting the tests into the same folders as the code for maintenance, but a single testing point with the suite file. And remember these are tests. They don't have to be optimized. They do however have to be thorough.
Aaron Mc Adam
@aaronmcadam
Apr 19 2017 14:50
Is it possible to create a lense that skips an index? so like lensIndex but the opposite sort of?
I want to assoc over a list of objects but skip a specific one
Michael Rosata
@mrosata
Apr 19 2017 14:51
@aaronmcadam maybe include something like
pathSatifies
Aaron Mc Adam
@aaronmcadam
Apr 19 2017 14:53
here's the code: https://goo.gl/JI0zTw
Michael Rosata
@mrosata
Apr 19 2017 14:54
what's the skip condition? Just an arbitary index?
Aaron Mc Adam
@aaronmcadam
Apr 19 2017 14:54
so I'm setting all the read values to false and then updating the 4th one to true
Michael Rosata
@mrosata
Apr 19 2017 14:54
ok
Aaron Mc Adam
@aaronmcadam
Apr 19 2017 14:54
yeah it's just for a demo :)
Aaron Mc Adam
@aaronmcadam
Apr 19 2017 15:27
The REPL is slow today, it's failing to load Sanctuary
GET https://wzrd.in/standalone/sanctuary@latest net::ERR_TIMED_OUT
GET https://wzrd.in/standalone/ramda-fantasy@latest net::ERR_TIMED_OUT
Michael Rosata
@mrosata
Apr 19 2017 15:42
@aaronmcadam Here is a solution of some-sort to the read setting https://goo.gl/ej4P4h
Jonah
@jonahx
Apr 19 2017 15:48
is there a list function that takes a transformer, and a predicate, and finds the first value of the list that, when transformed, satisfies the predicate, but returns the transformed value. ie, i want something thats equivalent to mapping the transformer over the list, then doing a R.find, but which works lazily — because map will do all the transformations first.
Aaron Mc Adam
@aaronmcadam
Apr 19 2017 15:54
would useWith work @jonahx?
thanks @mrosata, this looks cool
Jonah
@jonahx
Apr 19 2017 15:55
@aaronmcadam yes, i think so, just checking that there wasn’t a builtin i was missing...
Kurt Milam
@kurtmilam
Apr 19 2017 15:55
@jonahx sounds like you could also use reduce and return reduced when the predicate is satisfied.
Michael Rosata
@mrosata
Apr 19 2017 15:56
@aaronmcadam :thumbsup:
Jonah
@jonahx
Apr 19 2017 15:57
@kurtmilam true, i forgot about reduced. thx.
@aaronmcadam actually, don’t think you can use useWith as it will transform the entire argument first, so it would not end up being lazy
Aaron Mc Adam
@aaronmcadam
Apr 19 2017 16:00
ahh cool
Kurt Milam
@kurtmilam
Apr 19 2017 16:00
Sure thing. This sounds like a case for a function similar to F#'s tryPick (as explained to me by @polytypic earlier today)
Rick Medina
@rickmed
Apr 19 2017 16:07
deleted: unrelated
Aaron Mc Adam
@aaronmcadam
Apr 19 2017 16:21
I'd like to be able to call a function with either a single string or an array. Is there a way I could cast R.identity to an array? https://goo.gl/MLpwbK
I know I can change my flip(append) to use concat, but it's the casting
Robert Mennell
@skatcat31
Apr 19 2017 16:22
@jonahx What is this function supposed to do if the dataset doesn't meet predicate after transforming and testing everything?
Jonah
@jonahx
Apr 19 2017 16:24
@skatcat31 same as find: return undefined
Kurt Milam
@kurtmilam
Apr 19 2017 16:24
@skatcat31 Using reduce & reduced, you can return anything you'd like if none of the transformed items satisfy the predicate.
Just set your acc to whatever you want to have returned if none of the transformed items satisfy the predicate.
Robert Mennell
@skatcat31
Apr 19 2017 16:25
@jonahx so at worse case( not found ) it's a map and filter, but you're worried about array size?
Jonah
@jonahx
Apr 19 2017 16:27
@skatcat31 it's the composition of map and find (not filter) but retaining finds short circuit
@skatcat31 i probably should have just given the definition :)
const findWith = (fn, pred, list) => fn(find(x => pred(fn(x)), list))
Jonah
@jonahx
Apr 19 2017 16:32
which implementation is subtly flawed in that it unnecessarily has to run fn twice on the found value
ram-bot
@ram-bot
Apr 19 2017 16:34
Unexpected token )
require is not defined
Robert Mennell
@skatcat31
Apr 19 2017 16:34
ah you're trying to avoid the double transformation. Well since transformations are predictable this sounds like the predicate being passed is flawed. You should know in advance what you want in the untransformed data. Instead of having to test against a transformation, test against the original value the part you know SHOULD be there to satisfy what you need when transformed
Matthew Willhite
@miwillhite
Apr 19 2017 16:35
@ram-bot
const results = ['incomplete', 'complete', 'incomplete'];
reduce(
  compose(
    when(equals('complete'), reduced),
    nthArg(1)
  ), 
  'incomplete'
)(results);
ram-bot
@ram-bot
Apr 19 2017 16:35
'complete'
Denis Stoyanov
@xgrommx
Apr 19 2017 16:35
what is a goal?
Matthew Willhite
@miwillhite
Apr 19 2017 16:35
haha, sorry…had this in runkit. I may be late here, haven’t made it through the entire conversation. But this is an example of reduce/reduced going through a list lazily
Jonah
@jonahx
Apr 19 2017 16:38
@skatcat31 not sure i follow your last comment. to take a simple example, you have a list of numbers, and you want the first number whose square is greater than 100. you would like the function to return the squared value, not the original value. could you explain how your comment applies to that example?
Robert Mennell
@skatcat31
Apr 19 2017 16:40
@jonah so look at the countrapositive: you want a number whose square is greater than 100.... So look for a number who is greater than the square root of 100 instead
invert the transformation on the transformer and instead look for that root value
Jonah
@jonahx
Apr 19 2017 16:41
@skatcat31 but that assumes invertibility. i want a to find the first number on a list whose md5 hash contains the letter a at least 5 times, or whatever...
Robert Mennell
@skatcat31
Apr 19 2017 16:56
@jonahx reduceWhile
Jonah
@jonahx
Apr 19 2017 17:00
@skatcat31 that could be used to do it. but semantically it’s not really reduce. it really is “find this transformed thing”. i think my original question is answered though, which is that ramda doesn’t have a builtin specifically for this, but it’s pretty easy to implement a custom util.
Robert Mennell
@skatcat31
Apr 19 2017 17:04
@jonahx reduceWhile sounds almost exactly like what you want? transform, predicate. If the predicate is matched it will return the transformed value. Otherwise it will continue on
wait... no continues on is the problem... If it goes through the entire list... So you'd have to do reduceWhile with another test against the predicate afterwards...
Jonah
@jonahx
Apr 19 2017 17:07
@skatcat31 semantically reduce implies to me some function of all the list values like a sum or avg or max. ofc find can be implemented using reduce, but finding is a more specific concept
Kurt Milam
@kurtmilam
Apr 19 2017 17:18
Another use-case where a utility like this can be helpful is a router where you want to compare your current path to a bunch of routes and return the first match.
Kurt Milam
@kurtmilam
Apr 19 2017 17:24
@aaronmcadam Not sure whether this helps?
@ram-bot R.unapply( R.identity )( 'list' )
ram-bot
@ram-bot
Apr 19 2017 17:24
[ 'list' ]
Kurt Milam
@kurtmilam
Apr 19 2017 17:25
Also, FWIW:
@ram-bot R.unapply( R.identity )( 1, 2, 3 )
ram-bot
@ram-bot
Apr 19 2017 17:25
[ 1, 2, 3 ]
Kurt Milam
@kurtmilam
Apr 19 2017 17:29
@aaronmcadam I define this utility in most of my projects: const list = R.unapply( R.identity )
Denis Stoyanov
@xgrommx
Apr 19 2017 17:32
@kurtmilam ((...args) => console.log(args))(1,2,3)
Robert Mennell
@skatcat31
Apr 19 2017 17:33
@jonahx https://goo.gl/rVrg6t should do the job
Kurt Milam
@kurtmilam
Apr 19 2017 17:34
@xgrommx Indeed. Aaron was asking specifically about how to cast R.identity to an array. To be honest, I've been defining these kinds of utilities based on plain js recently, after having defined them based on Ramda methods for a while.
So a list utility in a more recent project would look like this:
@ram-bot
const list = ( ...args ) => [ ...args ]
list( 1, 2, 3 )
ram-bot
@ram-bot
Apr 19 2017 17:36
[ 1, 2, 3 ]
Kurt Milam
@kurtmilam
Apr 19 2017 17:37
Or this: const list = ( ...args ) => args :D
Stephan Meijer
@smeijer
Apr 19 2017 18:25
const filter = {};
if (task.state !== 'ALL') {
  filter.state = task.state === 'TODO' ? 'todo' : { $ne: 'todo' };
}
How would you guys clean this up with Ramda ?
ram-bot
@ram-bot
Apr 19 2017 18:56
{ state: 'ALL' }
Matthew Willhite
@miwillhite
Apr 19 2017 18:58
oops :grin:
Robert Mennell
@skatcat31
Apr 19 2017 18:58
@smeijer is $ne defined previously in the scope?
Brad Compton (he/him)
@Bradcomp
Apr 19 2017 18:59
It's a mongodb operator
Robert Mennell
@skatcat31
Apr 19 2017 19:00
somehow in this day and age I have yet to use a noSQL DB...
Stephan Meijer
@smeijer
Apr 19 2017 19:00
no, I'm creating a mongo selector. so filter.state is 'todo' when state is TODO, or Not-Equal to todo when 'DONE'. When 'ALL', filter.state must not be present.
this because my task state can be 'todo', 'locked', 'archived' and simply 'done'.
for user experience, 'done', also includes 'locked' and 'archived' for this filter
so simply said, if not 'todo', it's done :D
At the moment, i came up with:
const compact = R.filter(R.identity);
const stateMap = {
  ALL: null,
  DONE: { $ne: 'todo' },
  TODO: 'todo',
};

const filter = compact({
  user: user.id,
  state: stateMap[task.state],
});
Brad Compton (he/him)
@Bradcomp
Apr 19 2017 19:06
For what it's worth, I use reject(isNil) for compact so it will handle '', 0, and false correctly.
agstrauss
@agstrauss
Apr 19 2017 19:18
Hi everyone. I was wondering if there is an equivalent to assocPath but for nested arrays, thanks!
Galileo Sanchez
@galileopy
Apr 19 2017 19:24
@agstrauss like assocNested([0,0,1], [[[0]]], 1) === [ [ [0, 1]]]
Galileo Sanchez
@galileopy
Apr 19 2017 19:29
@ram-bot R.assocPath([ 0, 0, 1], 1, [[[0]]])
ram-bot
@ram-bot
Apr 19 2017 19:29
[ [ [ 0, 1 ] ] ]
Galileo Sanchez
@galileopy
Apr 19 2017 19:30
@agstrauss it works on arrays too
agstrauss
@agstrauss
Apr 19 2017 19:38
cool thanks!
Jonah
@jonahx
Apr 19 2017 20:05
@skatcat31 thanks
Robert Mennell
@skatcat31
Apr 19 2017 20:08
@jonahx don't forget you can curryN(3, findWith) if you want it curried so you can do partial applications