TL;DR
const and = (...fns) => (x) => fns.every(f => f(x))
const or = (...fns) => (x) => fns.some(f => f(x))
(work it out yourself if you can't be bothered reading 🙃)
You know the functional functions compose and pipe?
const pipe = (...fns) => (x) => fns.reduce((v, f) => f(v), x);
const compose = (...fns) => (x) => fns.reduceRight((v, f) => f(v), x);
Well, I was writing some code to detect if a window was tiled to the left of the screen, i.e. aligned to the left of the screen and full height.
I already had the functions isLeftAligned and isFullHeight and so wrote a new function isTiledLeft:
function isTiledLeft(window) {
    return isLeftAligned(window) && isFullHeight(window)
}
But I didn't like the repetition of window, heck what if there are more conditions to pass for the window to be considered tiled left?
In a spark of misguided insight I thought "Ah!, I can use compose"
const isTiledLeft = compose(isLeftAligned, isFullHeight)
and call it like this:
if (isTiledLeft(window)) {
    // Do something
}
Job done! Neat! Clean! Functional! Legend!
NOT! The more astute of you (and probably the downright stoners) would immediately know that this is not an application of compose!
The problem is that compose takes the output of each function and passes it to the next. isLeftAligned outputs true/false and compose then calls isFullHeight(true/false)!!! Doh! You're a legend in the same sense that Homer is a legend.
But it was so neat! I wanted to use compose 😞.
And straight after 💥 (I'm bipolar) - the signature of compose composed another idea in my head - i can use Array.every()
const and = (...fns) => (x) => fns.every(f => f(x))
const isTiledLeft = and(isLeftAligned, isFullHeight)
NICE!
And while I'm here I might as well do:
var isTiledRight = and(isRightAligned, isFullHeight)
and:
const or = (...fns) => (x) => fns.some(f => f(x))
And I did use compose after all, just not in code!
 
 
              
 
    
Top comments (0)