These are chat archives for ramda/ramda

7th
Dec 2018
phucnguyendk
@phucnguyendk
Dec 07 2018 03:39
Hi, I'm new in Ramda. Anybody can help to explain the meaning of this syntax Functor f => (a → b) → f a → f b
Johnny Hauser
@m59peacemaker
Dec 07 2018 03:41
hmm, I only don't understand the very first part
I see a function that takes a and returns b (a -> b)
so
wait yeah, I'm lost, too
I have to look at the manual, I don't do this enough
Johnny Hauser
@m59peacemaker
Dec 07 2018 03:50
> By replacing the argument names with their types, the body with the type of value it returns and the fat arrow, "=>", with a skinny one, "->", we get the signature:
hmph
But they aren't replacing the fat arrow
That's the part I don't get
Seems like it would be
Functor f -> (a → b) → f a → f b
Johnny Hauser
@m59peacemaker
Dec 07 2018 03:58
Anyway, it's curried stuff
eh, n/m I get this one other than why the =>, but I am not skilled at explaining this stuff
Mayer Lench
@mayerlench
Dec 07 2018 04:50
Hi, new to ramda and a big fan. Are there docs somewhere where i can learn how to read those function declarations that each ramda function has
Alexander Lichter
@manniL
Dec 07 2018 10:51
@ben-eb Thanks! :relaxed:
Alexander Lichter
@manniL
Dec 07 2018 11:38
Is there a nice method to create two lists from a list of lists with 2 elements each?
const fn = i=> {
  const heads = R.map(R.head)(i)
  const lasts = R.map(R.last)(i)
  return [heads, lasts]
}
Alexander Lichter
@manniL
Dec 07 2018 11:46
 const [dependencies, dependants] = R.juxt([R.map(R.head), R.map(R.last)])(i)
// Better but still not working "in parallel" :|
Riku Tiira
@rikutiira
Dec 07 2018 11:52
@manniL R.transpose(i)
Rocky Madden
@rockymadden
Dec 07 2018 12:49
@phucnguyendk Functor f => is a type constraint on f. So, when you then see f in (a → b) → f a → f b you know that they are functors. A functor, explained way simply, is a type which has a map method.
Daniel Pereira
@dpereira411
Dec 07 2018 12:59
proper way to call a function on a var that can be null, and if null just do nothing and return null?
just like swift flatMap on Optionals
do i need sanctuary for that?
Rocky Madden
@rockymadden
Dec 07 2018 13:06
Sanctuary would indeed work how you are describing if you first used something like S.toMaybe on it to get it into a Maybe type. There are also other ways to do what you are after.
Daniel Pereira
@dpereira411
Dec 07 2018 13:07
im using ramda only for now
Riku Tiira
@rikutiira
Dec 07 2018 13:11
I’m not sure if Ramda has any built-in maybe but you could do something like (fn) => R.when(R.complement(R.isNil), fn) yourself
Alexander Lichter
@manniL
Dec 07 2018 13:41
@rikutiira Dang, right! Many thanks :relaxed:
Barry G
@bgits
Dec 07 2018 14:02
If I want to update a field on an object(s) in a list of objects, where the object field matches a value. how would that look with ramada?
Daniel Pereira
@dpereira411
Dec 07 2018 14:06
@rikutiira thanks works perfect
Rocky Madden
@rockymadden
Dec 07 2018 14:20
@bgits I'd use a lens, personally. Check out the lens functions and then over.
Rocky Madden
@rockymadden
Dec 07 2018 14:27
Selwyn
@Siilwyn
Dec 07 2018 15:21
Hi, anybody knows if there is a ramda method for: [a].every(a1 => [b].find(a1))?
Scott Sauyet
@CrossEye
Dec 07 2018 15:32
@Siilwyn: with that a1 => ... treated as a boolean?
Alexander Lichter
@manniL
Dec 07 2018 15:33
const a = [1, 2, 3]
const b = [1, 2, 3, 4, 5]
const c = [0, 1, 2, 3]

const includesAll = R.pipe(
  flip(without),
  isEmpty
)

console.log(includesAll(a, b))
console.log(includesAll(c, b))
console.log(includesAll(b, c))
maybe like that?
(Results: true, false, false)
Selwyn
@Siilwyn
Dec 07 2018 15:33
@CrossEye positive. :)
@manniL yes nice! :clap:
Alexander Lichter
@manniL
Dec 07 2018 15:37
There might be a better way though :P
Scott Sauyet
@CrossEye
Dec 07 2018 15:39
without definitely feels too heavy-weight for this. I have to go right now, but I'll try to think of a more light-weight solution.
Alexander Lichter
@manniL
Dec 07 2018 15:39
Had the same feeling, yup
Selwyn
@Siilwyn
Dec 07 2018 15:39
Alright no worries. I was looking for the 'Relation' functions like intersection and stuff but got lost.
haha that's why I was asking
Alexander Lichter
@manniL
Dec 07 2018 15:41
You could also try using intersection + equals I guess
Alexander Lichter
@manniL
Dec 07 2018 20:12
Phew. Solved Day 7 finally. That was a bit of work

You can't use multiple lenses nicely with pipe I assume, right?

Eg:

const updateTodoTasks = state => {
  const done = R.view(doneLense)(state)
  const workers = R.view(workersLense)(state)
  const all = R.view(allTasksLense)(state)

  const inProgress = R.concat(R.pluck('letter', workers), done)

  return R.set(todoLense, R.difference(all, inProgress))(state)
}
Scott Sauyet
@CrossEye
Dec 07 2018 20:15
lenses compose fine, only in the opposite order than you expect.
view(compose(lensProp('foo'), lensProp('bar')), {foo: {bar: 42}}) //=> 42
Damn, I forgot to look at Day 7. Maybe this evening.
Scott Sauyet
@CrossEye
Dec 07 2018 20:23

@Siilwyn: I would write your function something like:

const subsetOf = (parent) => all(flip(includes)(parent))

but if you wanted it point-free, you could do this, I suppose:

const subsetOf = useWith(all, [flip(includes)])

or more rigorously:

const subsetOf = useWith(all, [flip(includes), identity])
Alexander Lichter
@manniL
Dec 07 2018 20:23

@CrossEye Oh yeah, I'm aware of that. But I mean, having an object with multiple properties like:

const obj = {
  foo: [1,2,3],
  bar: [2,3,4,5],
  something: [{baz:1}, {baz:2}]
}

And then trying to do something with foo, bar and something in "one pipe" (like the one try above) with the different properties

It feels somewhat dirty to call "state" everywhere. I can use juxt ofc but that won't remove the call on the return line
Scott Sauyet
@CrossEye
Dec 07 2018 20:27
I suppose you could use juxt. It doesn't add a lot, but does wrap up multiple functions to call against your data in one go. It's not a lens, though.
@mannil: Day7 looks like standard dependency graph resolution. Did you use one of the known algorithms for that, or did you create your own?
Alexander Lichter
@manniL
Dec 07 2018 20:31
@CrossEye I did not looked up anything
So no, did not use a "typical" algorithm.
But my data structure for part one sucked
Scott Sauyet
@CrossEye
Dec 07 2018 20:32
I remember creating an algorithm for exactly this, and then having a friend tell me it was one of the standard algorithms.
Alexander Lichter
@manniL
Dec 07 2018 20:32
Part 2 looked way cleaner
Scott Sauyet
@CrossEye
Dec 07 2018 20:32
I haven't seen part 2 yet.
Alexander Lichter
@manniL
Dec 07 2018 20:32
Wait for it :D
In the end it's a direct acyclic graph, so there are def. algorithms for it
Scott Sauyet
@CrossEye
Dec 07 2018 20:34
I assume the naive take doesn't work? Sort the letters and simply move the after of each before the before. That would be too trivial.
No, not with the random ordering. hmm
Alexander Lichter
@manniL
Dec 07 2018 20:34
well, the thing is you have to take a few things into account
  • No order
  • Possibly Multiple dependencies/dependants
  • Possibly Multiple Knots without deps
Scott Sauyet
@CrossEye
Dec 07 2018 20:47
Yes, and while the naive algorithm works for the small input, it fails on my actual sample. Might have to do regular topological sort of some "sort".
Alexander Lichter
@manniL
Dec 07 2018 21:21
@CrossEye Do you do the Alphabetical sort?
(As tiebreaker)
Scott Sauyet
@CrossEye
Dec 07 2018 21:39
I don't see any way to extend the naive algorithm to account for equivalent levels alphabetically. I thought I could, but it doesn't seem to work, and I think that makes sense. Coding it now much like the walk-through.
Rocky Madden
@rockymadden
Dec 07 2018 22:05
@manniL Is the source of these days something you can share? Sounds interesting.
Alexander Lichter
@manniL
Dec 07 2018 22:06
@rockymadden Sure! My solutions are up on GH. The puzzles itself can be found on https://adventofcode.com/
(PS: Better don't watch Day 7 Part one for now :joy: )
The others are.. "okay"
Rocky Madden
@rockymadden
Dec 07 2018 22:10
Love it, thank you!
Alexander Lichter
@manniL
Dec 07 2018 22:10
You are welcome :)
Feel free to suggest better approaches if you have some in mind! Always eager to optimize my code an learn @rockymadden
Scott Sauyet
@CrossEye
Dec 07 2018 22:31
@mannil, you're right. That felt harder than it should be, especially given that the final code is fairly simple.
Alexander Lichter
@manniL
Dec 07 2018 22:32
@CrossEye My problem was basically how to "express" myself in the language. Not how to solve the problem (algorithmically)
Scott Sauyet
@CrossEye
Dec 07 2018 22:33
Oh, that was a wonderful typo. Bring back "algorhythmically"!
Alexander Lichter
@manniL
Dec 07 2018 22:33
:joy:
Scott Sauyet
@CrossEye
Dec 07 2018 22:33
coding with a beat!
Alexander Lichter
@manniL
Dec 07 2018 22:34
I mostly do :P (Listen to music while I code)
Scott Sauyet
@CrossEye
Dec 07 2018 22:34
My previous algorithms for this sort of problem were iterative. This admits to a fairly nice recursive solution.
Alexander Lichter
@manniL
Dec 07 2018 22:34
Yup, I went with a recursion for part 2 as well
(or.. with R.until :P )
For part 1 I really have a typical recursion which isn't elegant in my case :sweat_smile:
Scott Sauyet
@CrossEye
Dec 07 2018 22:37
Haven't looked at part 2 yet. But if you want to see my part 1 it's at https://gist.github.com/CrossEye/d0f2eaf3c0bca55f74caf3541fc2f779
Alexander Lichter
@manniL
Dec 07 2018 22:40
Wow! That's indeed very elegant :+1:
Also the formatting looks interesting to me :P
What's the influence?
Scott Sauyet
@CrossEye
Dec 07 2018 22:44
It's a LISP-influenced style I've started trying to switch to. I've picked it up mostly by observing just how readable the posts from a certain StackOverflow user tend to be. We've actually discussed collaborating on a style guide. I might even try to start that this weekend.
I simply find her code extremely well thought out and well laid out.
Julien Gonzalez
@customcommander
Dec 07 2018 22:50
Interesting. I’ve recently adopted some conventions in ClojureScript whereby all endings brackets are put on the same line. Might as well be derived from LISP

So instead of

foo(
  bar(
    baz(3)
  )
)

Which is quite common to see in JS code, I now have

foo(
  bar(
    baz(3)));

Less visual noise IMHO :)

Scott Sauyet
@CrossEye
Dec 07 2018 22:56
Of course this has even less noise:
foo(bar(baz(3)))

But here I get Haskell jealousy:

foo bar baz 3

:smile:

And there are still times when my old, denser, style feels cleaner. There is still something to be said for this variant of the main function in that gist:
const partialOrder = (edges, nodes, order = [], node = firstFreeNode (edges, nodes)) => 
  edges.length == 0 
    ? order.concat(nodes)
    : partialOrder(removeEdgesFrom(node, edges), without(node, nodes), append(node,order))
The biggest problem with either version is probably the masochism in the arguments line used to work with just expressions rather than statements. (Sadism? Code is read more than it's written.)
Scott Sauyet
@CrossEye
Dec 07 2018 23:02
While order = [] is a very nice JS technique that helps avoid recursion helper functions, node = firstFreeNode(edges, nodes) is much more obscure. It's vaguely similar to Haskell's where clause, but put in the wrong place.
ok, part 2 looks like a job-scheduling algorithm. That one I've seen algorithms for years ago, but never written my own. Should be interesting, but will have to wait until after dinner!