These are chat archives for ramda/ramda

8th
Dec 2016
Jonah
@jonahx
Dec 08 2016 06:21

for tonight's AoC, you need a function that takes a matrix of booleans, and replaces the top left mxn corner of it with true, leaving the rest unchanged. I messed around doing it point-free with ramda, but the complexity of my solution always seemed greater than the complexity of doing nested loops with map:

function rect(m, n, scrn) {
  return scrn.map((row, i) => row.map((cell, j) => i<m && j<n ? true : cell));
}

is there a better (but still terse) way with ramda?

Kurt Milam
@kurtmilam
Dec 08 2016 12:09
The issue I run into most often when working with Ramda is that of an incorrect arity. I'm sure it's a type issue - something other than an integer is being passed in as the first argument to curryN and friends, but it's often difficult for me to figure out why that's happening. It's like it usually works, magic! But then there are the times it doesn't, and I fiddle around with it until I either get it working or give up.
Here's an example: https://goo.gl/dd25Rk
In that example, getSteps0 is the working function. getSteps is one of my attempts to swap the ternary operator out for an ifElse.
zfrs, bwAnd and xor are all binary functions, each of whose definitions I wrapped in R.curry.
I'd love some help figuring out where I'm going wrong in this example. Even more importantly, I'd really appreciate some help learning how to identify the arity issue and fix it quickly when I run into it in the future.
Jonah
@jonahx
Dec 08 2016 13:50
@kurtmilam I see a few (domain specific?) functions in there i’m not familiar with, but i don’t think it matters. I’m guessing the confusion is with ifElse. It expects functions, and will then call those functions with the same parameter that you pass to the entire ifElse statement. Eg:
const test1 = ifElse(equals(1), inc, dec);
test1(1); // => 2
test1(3); // => 2
As opposed to a ternary, which is simply evaluating one branch or the other.
Jonah
@jonahx
Dec 08 2016 14:00
@davidchambers Regarding your comment in this issue, could you explain where my mental model is wrong with chain? Because I thought anything that could be mapped could be chained. That chain was just a shorthand for a map followed by a flatten? Hence that my chain(head) would have been safe for any implementation….
Jonah
@jonahx
Dec 08 2016 14:09
It looks like head([1,2]) would need to return [1] rather than 1 to be compatible, is that correct?
Hardy Jones
@joneshf
Dec 08 2016 15:17
@kurtmilam I've found that for issues like what you're running into, it always comes down to me doing too much all at once. If I pull apart the functions into smaller pieces, the problem is usually seen pretty quickly and I can fix it.
@kurtmilam I've also found that if I try to be stubborn and diagnose where I went wrong without simplifying the problem, it generally takes hours. :)
@kurtmilam I don't mean that in a snarky way. This is really how it goes when I write programs.
@kurtmilam I'll spend way more time than necessary trying to figure out one little thing: reading docs, searching, reading papers, trying other examples.
@kurtmilam You'd think I'd know by now...
Hardy Jones
@joneshf
Dec 08 2016 15:23
Though interestingly, I'm much more apt to give it up after 5 minutes when it's work stuff. Maybe I'm just a glutton for punishment when it's personal projects.
Ugh, that's a pretty upsetting realization. :\
Kurt Milam
@kurtmilam
Dec 08 2016 15:24
This is total code golf and approximately my fourth of fifth layer of procrastination. I'm telling myself it'll help me improve my ramda skills.
Kurt Milam
@kurtmilam
Dec 08 2016 20:41
I'm trying to simplify this thing or at least make it more abstract. I'll have another go with it later. The domain
Drew
@dtipson
Dec 08 2016 20:47
the simplest example of something that can be mapped but not chained is Const, right? Const(9).map(x=>x+1) -> Const(9) but Const(9).chain(x=>Const(x+1)) wouldn't really make sense, because Const(9).map(I).join() makes no sense.
its functor interface is to ignore the function passed to it, so no possible function passed to map for Const[x] could ever result in a Const[Const[x]]
Drew
@dtipson
Dec 08 2016 20:55
and Maybe.safeHead(Array) is a natural transformation from any Array -> to a Maybe
Brad Compton (he/him)
@Bradcomp
Dec 08 2016 21:18
@dtipson Not exactly the same thing, but you might be interested in this article: http://blog.functorial.com/posts/2015-12-06-Counterexamples.html
David Chambers
@davidchambers
Dec 08 2016 23:54

It looks like head([1,2]) would need to return [1] rather than 1 to be compatible, is that correct?

That's exactly right, @jonahx. Also, to be clear chain(f) is equivalent to compose(unnest, map(f)). unnest only performs one level of "flattening". unnest is actually just another way to write chain(identity), so really we're saying that chain(f) is equivalent to compose(chain(identity), map(f)). I'm sure @joneshf could explain why these must be equivalent. It makes sense intuitively, though: either we map, creating excessive nesting, then remove the nesting with chain(identity), or we use chain to avoid creating the excessive nesting in the first place.