How to type a curried `map`?

Images
Related searches

I'm trying to type a curried map function in TypeScript. Here is the JavaScript equivalent:

const double = n => n * 2;
const map = f => arr => arr.map(f);
const doubleArr = map(double);

console.log(doubleArr([1, 2, 3]));
// ↳ [2, 4, 6]

Ideally, TypeScript should be able to infer, that after supplying double to map, doubleArray takes in an array of numbers and returns an array of numbers.

Here is what I tried:

const double = (n: number) => n * 2;
const map = (f: Function) => (arr: Array<any>) => arr.map(f);

But, TypeScript complains about f inside of map:

Argument of type 'Function' is not assignable to parameter of type '(value: any, index: number, array: any[]) => unknown'.
  Type 'Function' provides no match for the signature '(value: any, index: number, array: any[]): unknown'.

How would you type this function in TypeScript?

You can use the following declarations:

const double = (n: number) => n * 2;
const map = <A, R>(f: (arg: A) => R) => (arr: A[]) => arr.map(f);
const doubleArr = map(double); // (arr: number[]) => number[]

console.log(doubleArr([1, 2, 3]));
// ↳ [2, 4, 6]

Playground sample


Explanation: A and R are generic type parameters. map(double) returns a function with signature (arr: number[]) => number[], because TS is able to infer from double typings, that A and R both can only be number here.

Currying and Composing your own versions of Reduce, Filter and Map, We could take all arguments at once and then write another function to curry the trace function. That way we have both a regular and a curried� (One can write the type as Int x Int -> Int if you really mean the former -- but since all functions in Haskell are curried, that's not legal Haskell. Alternatively, using tuples, you can write (Int, Int) -> Int, but keep in mind that the tuple constructor (,) itself can be curried.) Much of the time, currying can be ignored by the new programmer.

You can declare an interface and then pass it instead of Function

interface ArrFunction<T> {
    (n: T): T
}

const double = (n: number) => n * 2;
const map = (f: ArrFunction<any>) => (arr: Array<any>) => arr.map(f);

Currying and Uncurrying in JavaScript and Flow, This is tedious, but we can write functions to curry any function of a In this way, curry and uncurry establish a mapping between functions� M. David Green demonstrates the concept of currying — a useful technique, to partially evaluate functions and make your functional JavaScript more readable.

You can create a function map with two parameters: array and function and when to want to use this function you should give an item from array to this function.

const double = (n: number) => n * 2;
const map = (arr: Array<any>, f: Function) => arr.map((item: any) => f(item));
map([1, 2, 3], double)

Curry and Function Composition. Note: This is part of the , We can write a function to compose as many functions as you like. For example , a curried version of map() can be specialized to do many� The arguments given to the curry() method are applied to the original (invoking) method/closure. The "curry()" method returns a closure as it's result. The arguments on the "curry()" method are passed, in their specified order, as the first (left-most) arguments of the original method/closure.

Curry — Toolz 0.10.0 documentation, Here we want to map the stem function onto each of the words produced by str. split . We want a stem_many function that takes a list of words, stems them, and� Curried form. On the other hand, the curried form is a better choice if the tuple of all arguments is not a stand-alone value with some useful meaning. For example, the power function pown 2.0 10 - the two arguments are the number to power and the exponent, but it is unlikely that you'd ever use the tuple (2.0, 10) somewhere else in your program.

[PDF] CSE 341 Lecture 8, ML includes a map function, but it is in curried form: fun map F [] = []. | map F (first:: rest) = (F first) :: (map F rest);. ▫ What is the type of this map function? Note that the curried function has any as its return type. This is to make the compiler relax, which would otherwise have to choose between returning type (y: number) => number and number. By specifying any, the responsibility of setting the return type is left to the developer that defines the overload signatures. General currying

It is partial application. If a three-argument function is curried and you call it as f(1), what you get back is not a two-argument function. You get back a one-argument function that returns another one-argument function. A curried function can only ever be passed one argument. The curry function in PrototypeJS is also not currying.

Comments
  • Thank you very much! Could you point me to the correct section in the docs that explains the <A, R> part? Or could you amend your answer explaining what's going on here?
  • This does compile now, but it doesn't correctly infer the type of doubleArr. const doubleArr: (arr: any[]) => any[]
  • you can improve it by doing next, const map = <T>(f: ArrFunction<T>) => (arr: Array<T>) => arr.map(f);
  • Hi Kamil, thank you for your help. I was looking for a curried map though!