DEV Community

Discussion on: Currying in TypeScript (just for fun)

Collapse
 
javier_toledo profile image
Javier Toledo • 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.