=== tests/cases/compiler/genericTypeParameterEquivalence2.ts === // compose :: (b->c) -> (a->b) -> (a->c) function compose(f: (b: B) => C, g: (a:A) => B): (a:A) => C { >compose : (f: (b: B) => C, g: (a: A) => B) => (a: A) => C >A : A >B : B >C : C >f : (b: B) => C >b : B >B : B >C : C >g : (a: A) => B >a : A >A : A >B : B >a : A >A : A >C : C return function (a:A) : C { >function (a:A) : C { return f(g.apply(null, a)); } : (a: A) => C >a : A >A : A >C : C return f(g.apply(null, a)); >f(g.apply(null, a)) : C >f : (b: B) => C >g.apply(null, a) : any >g.apply : (thisArg: any, argArray?: any) => any >g : (a: A) => B >apply : (thisArg: any, argArray?: any) => any >null : null >a : A }; } // forEach :: [a] -> (a -> ()) -> () function forEach(list: A[], f: (a: A, n?: number) => void ): void { >forEach : (list: A[], f: (a: A, n?: number) => void) => void >A : A >list : A[] >A : A >f : (a: A, n?: number) => void >a : A >A : A >n : number for (var i = 0; i < list.length; ++i) { >i : number >0 : number >i < list.length : boolean >i : number >list.length : number >list : A[] >length : number >++i : number >i : number f(list[i], i); >f(list[i], i) : void >f : (a: A, n?: number) => void >list[i] : A >list : A[] >i : number >i : number } } // filter :: (a->bool) -> [a] -> [a] function filter(f: (a: A) => boolean, ar: A[]): A[] { >filter : (f: (a: A) => boolean, ar: A[]) => A[] >A : A >f : (a: A) => boolean >a : A >A : A >ar : A[] >A : A >A : A var ret = []; >ret : any[] >[] : undefined[] forEach(ar, (el) => { >forEach(ar, (el) => { if (f(el)) { ret.push(el); } } ) : void >forEach : (list: A[], f: (a: A, n?: number) => void) => void >ar : A[] >(el) => { if (f(el)) { ret.push(el); } } : (el: A) => void >el : A if (f(el)) { >f(el) : boolean >f : (a: A) => boolean >el : A ret.push(el); >ret.push(el) : number >ret.push : (...items: any[]) => number >ret : any[] >push : (...items: any[]) => number >el : A } } ); return ret; >ret : any[] } // length :: [a] -> Num function length2(ar: A[]): number { >length2 : (ar: A[]) => number >A : A >ar : A[] >A : A return ar.length; >ar.length : number >ar : A[] >length : number } // curry1 :: ((a,b)->c) -> (a->(b->c)) function curry1(f: (a: A, b: B) => C): (ax: A) => (bx: B) => C { >curry1 : (f: (a: A, b: B) => C) => (ax: A) => (bx: B) => C >A : A >B : B >C : C >f : (a: A, b: B) => C >a : A >A : A >b : B >B : B >C : C >ax : A >A : A >bx : B >B : B >C : C return function (ay: A) { >function (ay: A) { return function (by: B) { return f(ay, by); }; } : (ay: A) => (by: B) => C >ay : A >A : A return function (by: B) { >function (by: B) { return f(ay, by); } : (by: B) => C >by : B >B : B return f(ay, by); >f(ay, by) : C >f : (a: A, b: B) => C >ay : A >by : B }; }; } var cfilter = curry1(filter); >cfilter : (ax: {}) => (bx: {}) => {}[] >curry1(filter) : (ax: {}) => (bx: {}) => {}[] >curry1 : (f: (a: A, b: B) => C) => (ax: A) => (bx: B) => C >filter : (f: (a: A) => boolean, ar: A[]) => A[] // compose :: (b->c) -> (a->b) -> (a->c) // length :: [a] -> Num // cfilter :: {} -> {} -> [{}] // pred :: a -> Bool // cfilter(pred) :: {} -> [{}] // length2 :: [a] -> Num // countWhere :: (a -> Bool) -> [a] -> Num function countWhere_1(pred: (a: A) => boolean): (a: A[]) => number { >countWhere_1 : (pred: (a: A) => boolean) => (a: A[]) => number >A : A >pred : (a: A) => boolean >a : A >A : A >a : A[] >A : A return compose(length2, cfilter(pred)); >compose(length2, cfilter(pred)) : (a: {}) => number >compose : (f: (b: B) => C, g: (a: A) => B) => (a: A) => C >length2 : (ar: A[]) => number >cfilter(pred) : (bx: {}) => {}[] >cfilter : (ax: {}) => (bx: {}) => {}[] >pred : (a: A) => boolean } function countWhere_2(pred: (a: A) => boolean): (a: A[]) => number { >countWhere_2 : (pred: (a: A) => boolean) => (a: A[]) => number >A : A >pred : (a: A) => boolean >a : A >A : A >a : A[] >A : A var where = cfilter(pred); >where : (bx: {}) => {}[] >cfilter(pred) : (bx: {}) => {}[] >cfilter : (ax: {}) => (bx: {}) => {}[] >pred : (a: A) => boolean return compose(length2, where); >compose(length2, where) : (a: {}) => number >compose : (f: (b: B) => C, g: (a: A) => B) => (a: A) => C >length2 : (ar: A[]) => number >where : (bx: {}) => {}[] }