These are chat archives for ramda/ramda

12th
Apr 2017
Robert Mennell
@skatcat31
Apr 12 2017 00:20
I wonder when internet API providers will start working on a communal guideline for how an API should behave...
Francesco Belladonna
@Fire-Dragon-DoL
Apr 12 2017 01:03
Hello everyone! I'm investigating the possibility to study and use Rambda in our usecase. I notice functions deal with immutable objects (deeply frozen) properly. However, they don't get frozen after running through ramda (even though they are cloned). Is there any option/function I can write that is run on any object that will give me the possibility to freeze objects automatically?
Matthew Willhite
@miwillhite
Apr 12 2017 02:41
@Fire-Dragon-DoL Do you have an example of what you are describing?
Francesco Belladonna
@Fire-Dragon-DoL
Apr 12 2017 02:49
@miwillhite sure! https://runkit.com/fire-dragon-dol/rambda-cloning I just want Object.isFrozen to be true without having to manually deeply freeze everything after I run Ramda functions
Francesco Belladonna
@Fire-Dragon-DoL
Apr 12 2017 03:02
to be true for everything in that example, I mean
Matthew Willhite
@miwillhite
Apr 12 2017 03:23
ah…like in the clone it freezes the cloned value?

you may look at calmm-js?

optics call Object.freeze on any new objects they create when NODE_ENV is not production.

Francesco Belladonna
@Fire-Dragon-DoL
Apr 12 2017 03:26
mhh... @miwillhite what if I need to run it in browser?
Matthew Willhite
@miwillhite
Apr 12 2017 03:27
idk I’m new to that lib, just stumbled across that section a few minutes ago and when applying it to your test case in runkit it seemed to work :sweat_smile:
Francesco Belladonna
@Fire-Dragon-DoL
Apr 12 2017 03:27
oh lol ok thanks
I wish rambda had a global function automatically run against any object before spitting them out so I could inject there
Matthew Willhite
@miwillhite
Apr 12 2017 03:29
btw, to avoid confusion…”rambda” is actually a different library, this channel is specific to “ramda” :grin:
Francesco Belladonna
@Fire-Dragon-DoL
Apr 12 2017 03:30
ahem, yes I refer to ramda, but I keep mistyping it, forgive me :P
Matthew Willhite
@miwillhite
Apr 12 2017 03:30
haha no problem…the other advertises to be a lighter version of ramda…to add to the confusion
Francesco Belladonna
@Fire-Dragon-DoL
Apr 12 2017 03:30
lol that's terrible
Philipp Wille
@Yord
Apr 12 2017 06:16
@Fire-Dragon-DoL have you considered seamless-immutable? (it does not help with automatic freezing, but it provides a function that can be applied either before or after applying any ramda function)
(it also freezes the output object though, which I assumed you wanted, since you use ramda)
Stephan Meijer
@smeijer
Apr 12 2017 09:04

@smeijer Here's an improved lens-based solution from the main developer of partial.lenses:
```js
const tasksForUser = id =>
[ 'tasks'
, L.elems
, L.when( L.any( R.equals( id ), [ 'users', L.elems, 'id' ] ) )
]

L.collect( tasksForUser( 1 ), list )
```

Okay, Seeing that and reading the partial.lenses docs, finally made me understand them a little. They are indeed as awesome as I expected.

I understand that the lense functionality in Ramda is just not as simple or good enough? partial.lenses is looking really awesome :sunglasses:

Francesco Belladonna
@Fire-Dragon-DoL
Apr 12 2017 09:05
yes @Yord that's one of my options. I just wanted ramda to automatically run the function for me because I'm lazy :P
Stephan Meijer
@smeijer
Apr 12 2017 09:06

@smeijer partial.lenses REPL

As for the repl, it was one of the two reasons I started using Ramda over Lodash (the other is the immutable part), but since we have VS-code with quokkajs. I never need a repl again :heart_eyes:

Kurt Milam
@kurtmilam
Apr 12 2017 09:21
@smeijer I believe, but am not certain, that you could do most of what partial.lenses does using ramda (lenses and other functions). It seems that partial.lenses has a number of shortcuts that eliminate some of the boilerplate.
I played with this a little more, extracting a reusable hasUserWithID function. The ease of lens composition and the read / writeability of the lenses makes for some very powerful, concise abstractions.
Stephan Meijer
@smeijer
Apr 12 2017 09:26
image.png
your gist is looking very clean indeed :grin:
Kurt Milam
@kurtmilam
Apr 12 2017 09:31
LOL that's the power of lenses. Can't get any more concise than that :D
I fixed the link ;)
Stephan Meijer
@smeijer
Apr 12 2017 09:49
I tweaked your last version a little bit:
// const hasUserWithID = id => L.when(L.any(R.equals(id), ['users', L.elems, 'id']));
const hasUser = user => L.when(L.any(R.whereEq(user), ['users', L.elems]));

// const tasksForUser = id => ['tasks', L.elems, hasUserWithID(id)];
const tasksForUser = user => ['tasks', L.elems, hasUser(user)];

// return an array of tasks having user.id === 1
L.collect(tasksForUser({ id: 1 }), list);

// set task.state to 'audit' on all tasks having user.id === 1
L.set([tasksForUser({ id: 1 }), 'state'], 'audit', list);
Just a case of personal taste I think. Now it can also be used to find / update based on username or email.
L.collect(tasksForUser({ username: 'JohnDoe' }), list);
Kurt Milam
@kurtmilam
Apr 12 2017 09:53
Perfect - I had considered abstracting the hasUser part out but hoped it would be obvious.
Stephan Meijer
@smeijer
Apr 12 2017 09:53
@mrosata was totally right. It is tricky first, but once you get the hang of it, it is so awesome.
Kurt Milam
@kurtmilam
Apr 12 2017 09:53
I agree. Glad you're finding them interesting and hopefully useful!
Stephan Meijer
@smeijer
Apr 12 2017 09:53
Obvious indeed. :) Thanks for your gist. It's a big help
Kurt Milam
@kurtmilam
Apr 12 2017 09:56
Yeah, I would have extracted that out if it were code I was writing in my own application. Glad you were able to see the pattern and take it further. I really don't think lenses are as complicated as a lot of people seem to think they are.
:)
Stephan Meijer
@smeijer
Apr 12 2017 10:02
I think it would become more simple when R.lensPathcould do the same thing as L.elems.
From the docs: var xHeadYLens = R.lensPath(['x', 0, 'y']);, it's not obvious how to do this with every element, like: (pseudo) R.lensPath(['x', R.elems, 'y']);
Kurt Milam
@kurtmilam
Apr 12 2017 10:03
I think you have to throw a map in there.
R.map( R.get( R.lensProp( 'y' ) ), R.lensProp( 'x' ) )
Stephan Meijer
@smeijer
Apr 12 2017 10:06

I expect something like that. But it's not in the docs, and googling around takes a lot of time to find something usefull on ramda. In a level that's easily understandable anyway. That makes it difficult to get a grasp on Ramda.

That being said. The community in this chat is awesome :smile: :sunglasses:

Kurt Milam
@kurtmilam
Apr 12 2017 10:07
Look at the benchmarks section on the partial.lenses docs. I think it's there that he mentions that L.modify(L.elems) is equivalent to (and much faster than) R.map.
This is a good community. Some super smart people hang out here, and most of the regulars are friendly and helpful.
Martin Broder
@mrtnbroder
Apr 12 2017 12:27
Anyone here familiar enough with flowtype that he could help me out?
I tried type Traversable<T> = { [string]: T } | Traversable<T> as traverseArray is recursive.
but that doesn’t work it looks like, cause when i return an array of strings for example
right here: traverseArray = (f, arr) => { return ['foobar'] }
it doesn’t complain. Though, it should.
Bravi
@Bravilogy
Apr 12 2017 12:48

hey guys,

const s = liftN(3, (a, b, c) => a + b + c)
s([1, 2], [2, 2], [3, 4])

can anyone explain how does this work please?
I thought it worked like this:

// 1 + 2 + 3 = 6
// 1 + 2 + 4 = 7
// 2 + 2 + 3 = 7
// 2 + 2 + 4 = 8
but i'm getting this answer:
// [6, 7, 6, 7, 7, 8, 7, 8]
Denis Stoyanov
@xgrommx
Apr 12 2017 12:50
@Bravilogy applicative, combine each with other
@Bravilogy this is a.map(x => y => z => x + y + z).ap(b).ap(c)
@Bravilogy lift with N=3 is 3 ap with of or map with 2 ap
Bravi
@Bravilogy
Apr 12 2017 12:52
aaah I seee so it would be
// 1 + 2 + 3 = 6
// 1 + 2 + 4 = 7
// 1 + 2 + 3 = 6
// 1 + 2 + 4 = 7
// 2 + 2 + 3 = 7
// 2 + 2 + 4 = 8
// 2 + 2 + 3 = 7
// 2 + 2 + 4 = 8
that makes sense now
phew :/
I was starting to doubt my maths
oh wow that's deep :D
Rob Halff
@rhalff
Apr 12 2017 12:59
how to apply a function multiple times with different parameters using ramda, like: (obj) => collection.reduce((obj, val) => func(val, obj), obj)
Denis Stoyanov
@xgrommx
Apr 12 2017 13:01
@rhalff sequence(always, repeat(add(10), 3))(10)
Rob Halff
@rhalff
Apr 12 2017 13:17
@xgrommx I basically want to change compose(removeItem('1'))(obj) to compose(removeItems(['1','2']))(obj), how to easily create the removeItems function?
Aaron Mc Adam
@aaronmcadam
Apr 12 2017 16:08
Hi everyone, I'm having a real brain freeze trying to work out how build a comma separated string from a list: https://goo.gl/xxqznQ
I think I need a reduction
Michael Rosata
@mrosata
Apr 12 2017 16:09
list.join(', ')
Aaron Mc Adam
@aaronmcadam
Apr 12 2017 16:09
I was tring that
Michael Rosata
@mrosata
Apr 12 2017 16:10
try baseStack.join(', ')
Aaron Mc Adam
@aaronmcadam
Apr 12 2017 16:10
I wasn't calling R.join correctly
Michael Rosata
@mrosata
Apr 12 2017 16:10
:smile:
Aaron Mc Adam
@aaronmcadam
Apr 12 2017 16:10
I was expecting the default to be a comma :D
Robert Mennell
@skatcat31
Apr 12 2017 16:10
in Ramda you can use join(',') to return a function that will call join on the array. In pute JS yo ucan use baseStack.join(',')
Aaron Mc Adam
@aaronmcadam
Apr 12 2017 16:11
so it was partially applying
thanks guys, my mind just went blank :D
Michael Rosata
@mrosata
Apr 12 2017 16:11
it happens :smile:
Brad Compton (he/him)
@Bradcomp
Apr 12 2017 17:52
R.map
@ram-bot
R.pluck('value', {a: {value: 1}, b: {value: 2}});
Huh, no ram-bot today
Robert Mennell
@skatcat31
Apr 12 2017 17:54
@ram-bot 1 + 1
guess not
Brad Compton (he/him)
@Bradcomp
Apr 12 2017 17:56
I was gonna start an interesting discussion on type signatures, but I like the visual aids
map :: Functor f => (a → b) → f a → f b
pluck :: k → [{k: v}] → [v]
prop :: s → {s: a} → a | Undefined
But pluck is defined in terms of map and prop
So shouldn't it be pluck :: Functor f => k -> f {k: v} -> f (v | Undefined)
Robert Mennell
@skatcat31
Apr 12 2017 17:59
Just a quick refresh for me:
map :: Functor f => (a -> b) -> f a -> f b means: map is defined as a Functor 'f' such that for the case of 'a' to 'b' then case 'f of a' will return the case 'f of b' right? That syntax for some reason still confuses me sometimes....( which admitidely makes no sense since I define my libraries in them most of the time on paper for interfaces...)
Michael Rosata
@mrosata
Apr 12 2017 17:59
I suppose, if there was a type checker
Brad Compton (he/him)
@Bradcomp
Apr 12 2017 18:00
For a type f that is a functor, map takes a function from a to b, and an containing an a, and returns an f containing a b
Robert Mennell
@skatcat31
Apr 12 2017 18:01
okay awesome. Thanks. For some reason my brain can't english good today
Michael Rosata
@mrosata
Apr 12 2017 18:02
well in pluck, k → [{k: v}] → [v] the [v] is a functor correct? so if the value of v is Undefined then [v] would fit the map signature f b ?
Brad Compton (he/him)
@Bradcomp
Apr 12 2017 18:02
My attempted example above was to demonstrate that pluck works on objects just fine, and that form is in fact quite useful for dealing with nested objects that have a regular structure.
Michael Rosata
@mrosata
Apr 12 2017 18:03
can you explain the last part of that a bit more? From after the comma
Brad Compton (he/him)
@Bradcomp
Apr 12 2017 18:03
But [] represents an array, not a Functor.

that form is in fact quite useful for dealing with nested objects that have a regular structure.

:question:

That part>
Michael Rosata
@mrosata
Apr 12 2017 18:04
arrays are functors basically though
yea that part
Robert Mennell
@skatcat31
Apr 12 2017 18:04

Whoops!

... case of 'a' to 'b' then...

That should be case of 'a to b' :point_up: April 12, 2017 10:59 AM

Brad Compton (he/him)
@Bradcomp
Apr 12 2017 18:08
Objects can represent different things - such as records- but they are also used as maps from strings to some known structure (often another object). In that case, map and pluck are useful functions for manipulating those objects. Specifically, pluck can be used for creating a new map by unnesting the objects in the original map.
In my case, I have keys mapping to objects representing data about UI components. At the end of the day though, I want to pull out (pluck) the values of those components. Initially I had used map(prop('value')) because I didn't consider that pluck could be used on anything other than arrays.
Michael Rosata
@mrosata
Apr 12 2017 18:10
I see what your saying
I guess that must be because map works on objects and as you said pluck is defined in terms of map
Brad Compton (he/him)
@Bradcomp
Apr 12 2017 18:13
Exactly. My further question is: Is that just an implementation detail, or does it make sense to codify that behavior in the type signature (i.e. make it more discoverable)
Robert Mennell
@skatcat31
Apr 12 2017 18:16
I think in this, since in JS an Array is the GoTo Functor they defined it in terms of Array so as to be recognizable to JS programmers, when in truth since pluck is in terms of a Functor it could applicable to any Functor. The problem comes in that Array is also many other things( traversable, etc...), so I think I get what you're saying
Brad Compton (he/him)
@Bradcomp
Apr 12 2017 18:17
Yeah. While Array a is an example of a Functor, the concept is obviously more broad.
Michael Rosata
@mrosata
Apr 12 2017 18:17
The weird part also is that an Object isn't a functor, it might just be accidental that pluck works on an object because map does
Robert Mennell
@skatcat31
Apr 12 2017 18:17
I think it stems form the fact that Pluck's definition is all the way back from 0.1.0, so it could just be legacy definition in need of an update
@mrosata I feel like that logic is slightly flawed? Pluck doesn't work on objects, only functors:
http://ramdajs.com/repl/?v=0.23.0#?R.pluck%28%27a%27%29%28%7Ba%3A%201%7D%29%3B
Michael Rosata
@mrosata
Apr 12 2017 18:19
that could be true @skatcat31
but pluck will work with objects because map is defined using a switch statement that checks for type
Gabe Johnson
@gabejohnson
Apr 12 2017 18:20
@ram-bot
pluck('a', {b: {a:1}});
Syaiful Bahri
@syaiful6
Apr 12 2017 18:20
i think it more practical, as user i don't want that undefined on the array.
Gabe Johnson
@gabejohnson
Apr 12 2017 18:21
@ram-bot
R.pluck('a', {b: {a:1}});
Michael Rosata
@mrosata
Apr 12 2017 18:21
so while pluck might not be intended for objects, because it maps with map it would handle object (even though it might never have meant to be used that way)
Gabe Johnson
@gabejohnson
Apr 12 2017 18:21
@ram-bot
R.pluck('a', {b: {a:1}});
huh
Robert Mennell
@skatcat31
Apr 12 2017 18:21
@gabejohnson :point_up: April 12, 2017 10:52 AM
Gabe Johnson
@gabejohnson
Apr 12 2017 18:22
ahhh..thx @skatcat31
Robert Mennell
@skatcat31
Apr 12 2017 18:25
@mrosata this is because to make an Object a Functor, you just need to do a dictionary traverse over it's keys using a reducer, so Ramda map makes Objects-> Functors by... well:
_reduce(function(acc, key) {
        acc[key] = fn(functor[key]);
        return acc;
      }, {}, keys(functor));
Michael Rosata
@mrosata
Apr 12 2017 18:27
@skatcat31 I understand the implementation. But if we're talking type signatures we wouldn't be including implementation details
Robert Mennell
@skatcat31
Apr 12 2017 18:28
@mrosata true, but it's such a common use case it was just embedded into Ramda
so it doesn't work on Objects perse... it works on Dictionary(ies)
Michael Rosata
@mrosata
Apr 12 2017 18:29
Yea, I think it's great, when I write my own map functions I include support for Objects too, I think it's very handy
Robert Mennell
@skatcat31
Apr 12 2017 18:34
@mrosata Well I mean Dictionary is a functor and in JS Object == Dictionary (loosely)
Michael Rosata
@mrosata
Apr 12 2017 18:36
The pojo doesn't have a map method though. It is loosely referred to as a dictionary by a lot of people
:point_up: April 12, 2017 11:36 AM :+1:
Michael Rosata
@mrosata
Apr 12 2017 18:38
I will agree that JS does have a lot of weird 'features', lol. I'll be back after some lunch :)
Robert Mennell
@skatcat31
Apr 12 2017 18:42
@mrosata typeof makes it even more confusing XD
Brad Compton (he/him)
@Bradcomp
Apr 12 2017 19:07
Ramda has deliberately defined a Functor instance for Objects. Sanctuary has Functor defined for Object as well
Sorry, was at lunch there
Objects in JS can be records, dictionaries, and objects in the OO sense. I agree that Functor really only makes sense if it's used as a Dictionary, but in those cases it can be very useful
Robert Mennell
@skatcat31
Apr 12 2017 19:09
:+1:
Brad Compton (he/him)
@Bradcomp
Apr 12 2017 19:11
And I think that pluck does make sense for other Functors as well.
pluck('firstName', Just({firstName: 'Mr.', lastName: 'T'}))
Robert Mennell
@skatcat31
Apr 12 2017 19:14
@Bradcomp submit a pull request changing that definition? I don't think anyone here disagrees it's definition is out of date
Brad Compton (he/him)
@Bradcomp
Apr 12 2017 19:15
Haha, yeah, that was where I was going with this. I'll have to wait until tonight to work on it though
Michael Rosata
@mrosata
Apr 12 2017 19:15
@skatcat31 lol, yea typeof is kindof weird. I think more than likely the sense of greatness developers associate with JavaScript has a lot less to do with the great features of the JavaScript language and more or less the greatness of the JavaScript community
Gabe Johnson
@gabejohnson
Apr 12 2017 19:18
@Bradcomp interestingly it looks like Sanctuary's pluck is not generalized for Functors
It would be a very minor change to make it so though
Brad Compton (he/him)
@Bradcomp
Apr 12 2017 19:19

pluck(k, xs) is equivalent to map(prop(k), xs).

Interesting...

Robert Mennell
@skatcat31
Apr 12 2017 19:19
@Bradcomp I was wondering if you had seen that
Brad Compton (he/him)
@Bradcomp
Apr 12 2017 19:19
Yeah
I hadn't
Mick Dekkers
@mickdekkers
Apr 12 2017 19:34
Could anyone help me figure out why R.pipeK(f, g) works in this setup when R.pipe(R.chain(f), R.chain(g)) does not?
https://runkit.com/soullesswaffle/58ed1999e5b718001401569c
The documentation says they're equivalent :/
Brad Compton (he/him)
@Bradcomp
Apr 12 2017 19:37
I think the documentation is wrong then. Should be
pipe(
    fnA,
    chain(fnB)
)
Mick Dekkers
@mickdekkers
Apr 12 2017 19:38
Oh good, I'm not going crazy then :sweat_smile:
Thanks!
Brad Compton (he/him)
@Bradcomp
Apr 12 2017 19:38
With the chain around fnA you are saying that your function expects a monad to be passed in initially
Mick Dekkers
@mickdekkers
Apr 12 2017 19:40
Is there anywhere I can read up on (or watch video on) chain? I have a basic understanding of what monads are but I'm not sure I fully understand chain yet
Gabe Johnson
@gabejohnson
Apr 12 2017 19:44
@SoullessWaffle, do you know flatMap?
Mick Dekkers
@mickdekkers
Apr 12 2017 19:46
@gabejohnson I think so; to my understanding it's like map but it accepts a function that returns a Monad (of the same type) and it 'flattens' the return value of that function get the value inside the monad
Gabe Johnson
@gabejohnson
Apr 12 2017 19:46
:boom:
That's chain
Mick Dekkers
@mickdekkers
Apr 12 2017 19:46
I have @mpj's Nordic.js video to thank for that explanation ;)
So chain === flatMap
Gabe Johnson
@gabejohnson
Apr 12 2017 19:48
yep
Mick Dekkers
@mickdekkers
Apr 12 2017 19:48
Which is the exact same question I asked on the fantasy-land channel yesterday, oops :sweat_smile:
Okay, so am I correct in assuming that every kind of Monad has (or can have) one 'value'?
Gabe Johnson
@gabejohnson
Apr 12 2017 19:50
What's the value of the Monad [1, 2, 3]?
Brad Compton (he/him)
@Bradcomp
Apr 12 2017 19:50
Well, you have something like Array which contains multiple values
Beat me to it
Mick Dekkers
@mickdekkers
Apr 12 2017 19:50
In the case of array (if we were to pretend it has flatMap for a second), the value could be the set of data
but yes I suppose that does contain multiple values
and map gets called on each one of them, so that makes more sense
Brad Compton (he/him)
@Bradcomp
Apr 12 2017 19:53
map((x) => ([x + 1]), [1, 2, 3])   //[[2], [3], [4]]
chain((x) => ([x + 1]), [1, 2, 3]) //[2, 3, 4]
Mick Dekkers
@mickdekkers
Apr 12 2017 19:54
Huh, this is some pretty interesting stuff. So it's possible to implement your own Monads into different data types, by giving them chain and of methods?
Brad Compton (he/him)
@Bradcomp
Apr 12 2017 19:54
Yes!
Mick Dekkers
@mickdekkers
Apr 12 2017 19:54
Great example, @Bradcomp. That really 'clicks' in my head.
Brad Compton (he/him)
@Bradcomp
Apr 12 2017 19:54
Thanks :-D
Mick Dekkers
@mickdekkers
Apr 12 2017 19:56
Btw, is it true that Monads are by definition also Functors?
I've heard people say this before but I don't see it in the fantasy-land spec, unless I'm missing something
Brad Compton (he/him)
@Bradcomp
Apr 12 2017 19:58
Yes. It's represented by the Diagram
Gabe Johnson
@gabejohnson
Apr 12 2017 19:58
@SoullessWaffle looking at the diagram you can see that they are
Now you beat me!
Robert Mennell
@skatcat31
Apr 12 2017 19:59
Functor -> Apply -> Applicative -> Monad && Functor -> Apply -> Chain -> Monad
Mick Dekkers
@mickdekkers
Apr 12 2017 19:59
Oh neat, there's a diagram!
I guess I did miss something :D
Robert Mennell
@skatcat31
Apr 12 2017 20:01
... An Array is really a Traversable... that makes so much more sense now...
:boom:
Denis Stoyanov
@xgrommx
Apr 12 2017 20:05
Traverse this like a functor with applicative effect
Robert Mennell
@skatcat31
Apr 12 2017 20:05
:+1:
Denis Stoyanov
@xgrommx
Apr 12 2017 20:06
if u use Identity it will be like a functor
Rick Medina
@rickmed
Apr 12 2017 20:14
@xgrommx awesome description of traverse
Denis Stoyanov
@xgrommx
Apr 12 2017 20:17
@rickmed yes, because Identity doesn't has some effect that traverse with Identity is a Functor. As a functor, traverse keep structure but has an applicative effect.
Mick Dekkers
@mickdekkers
Apr 12 2017 20:19
Is it somehow possible to put a Reader in the env of another Reader and call it in there transparently? (i.e. without having to call run on it)
In my case I have some functions that require configuration, but for some of these functions, their configuration contains other functions that require configuration
But I'm not sure how to compose them neatly
Denis Stoyanov
@xgrommx
Apr 12 2017 20:22
@rickmed as u can see sequence [Just 10, Just 20] => Just [10,20] array of 2 elements after and before sequence but has an applicative effect from Maybe
@SoullessWaffle chain?
Rick Medina
@rickmed
Apr 12 2017 20:24
@xgrommx yeap I was just thinking of "like a functor with applicative effect" in terms of map + sequence
Denis Stoyanov
@xgrommx
Apr 12 2017 20:25
@rickmed so, if u can write functor u can write traverse (keep in mind)
Rick Medina
@rickmed
Apr 12 2017 20:26
:)
Mick Dekkers
@mickdekkers
Apr 12 2017 20:26
@xgrommx maybe. For example say I have a parseDate function which takes a string and outputs a Date. As part of its env it could set the timezone of the date.
Then I have some other functions (that happen to be Readers themselves) and that use parseDate to e.g. evolve some prop on an object
Denis Stoyanov
@xgrommx
Apr 12 2017 20:29
@rickmed nice example)
instance Functor Tree where
  fmap f Nil = Nil
  fmap f (Branch l x r) = Branch (fmap f l) (f x) (fmap f r)

instance Foldable Tree where
  foldr f z Nil = z
  foldr f z (Branch l x r) = foldr f (f x (foldr f z r)) l

instance Traversable Tree where
  traverse f Nil = pure Nil
  traverse f (Branch l x r) = liftA3 Branch (traverse f l) (f x) (traverse f r)
traverse vs fmap
Mick Dekkers
@mickdekkers
Apr 12 2017 20:33
to give a more concrete example, I would like to refactor this codebase to use Readers: https://github.com/SoullessWaffle/nodejs-ns-api/blob/fp/src/processors/departures.js#L24-L85
Right now I'm using dependency injection to pass the parseDate function which is used on line 70
But that function itself requires configuration: https://github.com/SoullessWaffle/nodejs-ns-api/blob/fp/src/index.js#L44
Denis Stoyanov
@xgrommx
Apr 12 2017 20:34
@SoullessWaffle Reader is a some wrapper for Function monad
Rick Medina
@rickmed
Apr 12 2017 20:35
@xgrommx :fire:
Mick Dekkers
@mickdekkers
Apr 12 2017 20:36
@xgrommx Sorry, what do you mean by that?
Tristin Forbus
@tforbus
Apr 12 2017 22:19

hi all, trying to put this into a function and make it point free, but not sure if it's possible.

let's say i want to set the id of my request object to be the id of its first child:
myFunction = request => {
path = R.path(['children', 0, 'id']),
return R.assoc('id', path(request), request)
}

// request = { children: [ { id: 1 }, { id: 2 } ] }
// myFunction(request) => { id: 1, children: [ { id: 1 }, { id: 2 } ] }

Brad Compton (he/him)
@Bradcomp
Apr 12 2017 22:26
@tforbus You can use R.converge for that sort of thing. Often times it's less readable though https://goo.gl/V4CcrJ
Tristin Forbus
@tforbus
Apr 12 2017 22:27
@Bradcomp nice, thanks for the tip