It's hard to write currying definitions, at least in a way that is readable.
I would do is to extract the signatures outside of the function declaration as much as possible, something like this:
type Ord = string | number;
type ThirdFunction = (objs: Ord[]) => boolean;
type SecondFunction = (objs: Ord[]) => ThirdFunction;
type FirstFunction = (fn: (o: Ord) => (o: Ord) => boolean) => SecondFunction;
const arrayCompare: FirstFunction = f => ([x,...xs]) => ([y,...ys]) => {
...
}
(code in playground)
I also removed the declare
you had before the Ord
type alias, there's no need for it. And you can find better names for the types.
Another thing is that you don't need to specify the boolean
here:
const eq = (x: Ord) => (y: Ord) : boolean => x === y;
Can be:
const eq = (x: Ord) => (y: Ord) => x === y;
Or you could express the function using a single type
declaration. Readability is fairly decent, all things considered.
type Ord = number | string;
type arrayCompareFunc = (f: (x: Ord) => (y: Ord) => boolean)
=> (xs: Ord[])
=> (ys: Ord[])
=> boolean;
const arrayCompare: arrayCompareFunc = f => ([x,...xs) => ([y,...ys) => {
...
};