These are chat archives for ramda/ramda

24th
Jul 2016
Jigar Gosar
@jigargosar
Jul 24 2016 11:04
is functor a function or a "Type that can be mapped over" or both?
David Chambers
@davidchambers
Jul 24 2016 11:27
@jigargosar, the latter.
Jigar Gosar
@jigargosar
Jul 24 2016 11:55
@xgrommx that is the problem :(
too many definitions
but according to category theory, functior is a Type that can be mapped over? right
Jigar Gosar
@jigargosar
Jul 24 2016 12:38
can this be simplified further, made more readable?
var addAdjacentNums = function (list) {
                var pairToNum = function (shouldBeZero, numPair) {
                    if (shouldBeZero) return [false, 0];
                    if (numPair[0] === numPair[1]) {
                        return [true, numPair[0] + numPair[1]]
                    }
                    return [false, numPair[0]]
                };
                var adjacentPairs = _.aperture(2, list);
                var mapAccum = _.mapAccum(pairToNum, false, adjacentPairs);
                return mapAccum[1];
            };
this is part of the logic for the swipe left action in a 2048 game.
Aldwin Vlasblom
@Avaq
Jul 24 2016 13:18
@jigargosar Why is pairToNum nested within addAdjacentNums? It seems like you're not using any of the enclosed variables, so moving it outside makes it more readable and more performant.
Jigar Gosar
@jigargosar
Jul 24 2016 13:38
@Avaq you are right.
Aldwin Vlasblom
@Avaq
Jul 24 2016 13:39
And you'll be able to unit-test pairToNum separately. ;)
Jigar Gosar
@jigargosar
Jul 24 2016 13:39
it so happens, pairToNum is not useful outside the context. I tend to group such methods together.
here is my second attempt
also finding a good name for pairToNum, which is not a normal fn, but a mapAccum fn, is hard. :)
           var addAdjacentNums2 = function (list) {
                var range = _.range(0, _.length(list));
                return _.reduce(function (list, idx) {
                    var lens1 = _.lensIndex(idx);
                    var lens2 = _.lensIndex(idx + 1);
                    var lensViewEquals = _.converge(_.equals, [_.view(lens1), _.view(lens2)]);
                    if (lensViewEquals(list)) {
                        return _.compose(_.set(lens2, 0), _.over(lens1, _.multiply(2)))(list);
                    }
                    return list;
                }, list, range);
            };
here lensViewEquals can be moved out. since it is generic enough to make sense just by the name.
es6 destructuring can help a lot to work with pairs. otherwise, pairs are too cumbersome :(
Jigar Gosar
@jigargosar
Jul 24 2016 13:45
here I could have used an apperture of 2 lens, to iterate over. so as to avoid range and playing with idx.
Aldwin Vlasblom
@Avaq
Jul 24 2016 13:45
Ah, I see. Something like pairToNumAccumulator, accumulatePairsToNumbers might be a nice way to name these kinds of functions.
Jigar Gosar
@jigargosar
Jul 24 2016 13:46
thats a great suggestion, will use acc prefix/suffix to make it explicit.
@Avaq thanks.
Jigar Gosar
@jigargosar
Jul 24 2016 13:51
            var addAdjacentNums3 = function (list) {
                list = _.append(0,list);
                var lensPairs = _.compose(_.aperture(2), _.times(_.lensIndex), _.length)(list);
                return _.reduce(function (list, lensPair) {
                    var lens1 = lensPair[0];
                    var lens2 = lensPair[1];
                    if (viewEq(lens1, lens2)(list)) {
                        return _.compose(_.set(lens2, 0), _.over(lens1, _.multiply(2)))(list);
                    }
                    return list;
                }, list, lensPairs);
            };
this one seems more redable.
Jigar Gosar
@jigargosar
Jul 24 2016 13:58
now even shorter
var addAdjacentNums3 = function (list) {
                var lensPairs = _.compose(_.aperture(2), _.times(_.lensIndex), _.length)(list);
                return _.reduce(function (list, lensPair) {
                    var lens1 = lensPair[0];
                    var lens2 = lensPair[1];
                    return _.when(viewEq(lens1, lens2), updateList(lens1, lens2))(list);
                }, list, lensPairs);
            };
Ramda keeps giving and giving. ;)
and more redable.
Aldwin Vlasblom
@Avaq
Jul 24 2016 14:04
Would something like this work? I've simply taken the imperative operations and extracted them to functions for composition:
var toLensPairs = _.compose(_.aperture(2), _.times(_.lensIndex), _.length);
var reducePairs = _.reduce(function (list, lensPair) {
    var lens1 = lensPair[0];
    var lens2 = lensPair[1];
    return _.when(viewEq(lens1, lens2), updateList(lens1, lens2))(list);
});
var addAdjacentNums3 = _.ap(reducePairs, toLensPairs);