DEV Community


Discussion on: Currying in TypeScript (just for fun)

teclado profile image
Teclado Mugriento • Edited

First time I've seen that bind method. Quite enlightning.
In the other hand, you might get used to infinite recursion

let cat = (a) => {
    return {
        value: a,
        cat: (b) => cat(a + ' ' + b)
Enter fullscreen mode Exit fullscreen mode
javier_toledo profile image
Javier Toledo Author • Edited

That's basically one stateful way of implementing function composition, which in Haskell is trivial with the . operator:

cat :: String -> String -> String
cat a b = a ++ " " ++ b

let result = cat "a" . cat "b" . cat "c" $ "d" -- the $ operator is just a way to call the composed function with the parameter "d"
-- result == "a b c d"

In TypeScript, there are some libraries that implement function composition like fp-ts, but you can create your own pretty easily using Array.prototype.reduceRight:

let cat: (a: string) => (b: string) => string =
    (a) => (b) => a + ' ' + b

const compose = (...fns: Function) => (argument: any) => fns.reduceRight((v, f) => f(v), argument)

console.log(compose(cat('a'), cat('b'), cat('c'))('d'))
// => "a b c d"

In this compose implementation, we're using currying again to build a function that expects the parameter of the final composition to be used as the initial value for the reduceRight function. reduceRight iterates our functions from right to left, resolving each function and passing its return value as an argument to the previous one.