I'm currently looking into Haskell and i'm fascinated by some of its features, for example the end-recursive functions using an accumulator.
Questions:
And if so, how would you write this for example in javascript:
power_acc :: Double -> Int -> Double
power_acc x y = power_acc_h x y 1
power_acc_h :: Double -> Int -> Double -> Double
power_acc_h x 0 acc = acc
power_acc_h x y acc = power_acc_h x (y-1) (acc*x)
Is there a construct in javascript similar to that?
Yes, you can literally translate this to JS:
function power_acc(x, y) { // Double -> Int -> Double
y = y>>>0; // cast to positive int (avoiding nontermination)
return power_acc_h(x, y, 1);
}
function power_acc_h(x, y, acc) { // Double -> Int -> Double -> Double
return y == 0
? acc
: power_acc_h(x, y-1, acc*x);
}
Or does it even make sense regarding efficiency since javascript is not as functional as Haskell?
With ES6, tail recursion is fully supported in JS, and you'll get the same efficiency as with a loop (and possibly even better than haskell, as you don't create lazy multiplications).
Is there any library like ramda, lodash, ... that supports this way of programming
No library required. Although I'm sure there are libs that simplify type checking or offer nicer notation for pattern matching.
How would you write this for example in javascript?
You'd use a while loop. All accumulation functions in haskell are written this way because they can be directly optimised into a loop, and that's the notation you should use for this construct in JS (as most programmers are familiar with it):
function power_acc(x, y) { // Double -> Int -> Double
y = y>>>0; // cast to positive int (avoiding nontermination)
var acc = 1;
while (y != 0) {
acc *= x;
y -= 1;
}
return acc;
}
Mutating local variables is no harm, your function is still pure. If you're looking for an even shorter notation, use a for loop.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With