Skip to content

Commit f4a07ae

Browse files
committed
Add some tests for existing behavior inferring from generic functions.
1 parent ed728f1 commit f4a07ae

20 files changed

+7726
-0
lines changed
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
tests/cases/compiler/genericTypeParameterEquivalence2strict.ts(41,22): error TS2345: Argument of type '<A>(f: (a: A) => boolean, ar: A[]) => A[]' is not assignable to parameter of type '(a: {}, b: {}) => {}[]'.
2+
Types of parameters 'f' and 'a' are incompatible.
3+
Type '{}' is not assignable to type '(a: {}) => boolean'.
4+
Type '{}' provides no match for the signature '(a: {}): boolean'.
5+
tests/cases/compiler/genericTypeParameterEquivalence2strict.ts(59,20): error TS2345: Argument of type '<A>(ar: A[]) => number' is not assignable to parameter of type '(b: {}) => number'.
6+
Types of parameters 'ar' and 'b' are incompatible.
7+
Type '{}' is not assignable to type '{}[]'.
8+
Property 'length' is missing in type '{}'.
9+
tests/cases/compiler/genericTypeParameterEquivalence2strict.ts(64,20): error TS2345: Argument of type '<A>(ar: A[]) => number' is not assignable to parameter of type '(b: {}) => number'.
10+
11+
12+
==== tests/cases/compiler/genericTypeParameterEquivalence2strict.ts (3 errors) ====
13+
// compose :: (b->c) -> (a->b) -> (a->c)
14+
function compose<A, B, C>(f: (b: B) => C, g: (a:A) => B): (a:A) => C {
15+
return function (a:A) : C {
16+
return f(g.apply(null, a));
17+
};
18+
}
19+
20+
// forEach :: [a] -> (a -> ()) -> ()
21+
function forEach<A>(list: A[], f: (a: A, n?: number) => void ): void {
22+
for (var i = 0; i < list.length; ++i) {
23+
f(list[i], i);
24+
}
25+
}
26+
27+
// filter :: (a->bool) -> [a] -> [a]
28+
function filter<A>(f: (a: A) => boolean, ar: A[]): A[] {
29+
var ret: A[] = [];
30+
forEach(ar, (el) => {
31+
if (f(el)) {
32+
ret.push(el);
33+
}
34+
} );
35+
36+
return ret;
37+
}
38+
39+
// length :: [a] -> Num
40+
function length2<A>(ar: A[]): number {
41+
return ar.length;
42+
}
43+
44+
// curry1 :: ((a,b)->c) -> (a->(b->c))
45+
function curry1<A, B, C>(f: (a: A, b: B) => C): (ax: A) => (bx: B) => C {
46+
return function (ay: A) {
47+
return function (by: B) {
48+
return f(ay, by);
49+
};
50+
};
51+
}
52+
53+
var cfilter = curry1(filter);
54+
~~~~~~
55+
!!! error TS2345: Argument of type '<A>(f: (a: A) => boolean, ar: A[]) => A[]' is not assignable to parameter of type '(a: {}, b: {}) => {}[]'.
56+
!!! error TS2345: Types of parameters 'f' and 'a' are incompatible.
57+
!!! error TS2345: Type '{}' is not assignable to type '(a: {}) => boolean'.
58+
!!! error TS2345: Type '{}' provides no match for the signature '(a: {}): boolean'.
59+
60+
declare function strBool(str: string): boolean
61+
const filterer = cfilter(strBool);
62+
const expectFilterer: (a: string[]) => string[] = filterer;
63+
64+
const filtered = filterer(["hello"]);
65+
const expectFiltered: string[] = filtered;
66+
67+
// compose :: (b->c) -> (a->b) -> (a->c)
68+
// length :: [a] -> Num
69+
// cfilter :: {} -> {} -> [{}]
70+
// pred :: a -> Bool
71+
// cfilter(pred) :: {} -> [{}]
72+
// length2 :: [a] -> Num
73+
// countWhere :: (a -> Bool) -> [a] -> Num
74+
75+
function countWhere_1<A>(pred: (a: A) => boolean): (a: A[]) => number {
76+
return compose(length2, cfilter(pred));
77+
~~~~~~~
78+
!!! error TS2345: Argument of type '<A>(ar: A[]) => number' is not assignable to parameter of type '(b: {}) => number'.
79+
!!! error TS2345: Types of parameters 'ar' and 'b' are incompatible.
80+
!!! error TS2345: Type '{}' is not assignable to type '{}[]'.
81+
!!! error TS2345: Property 'length' is missing in type '{}'.
82+
}
83+
84+
function countWhere_2<A>(pred: (a: A) => boolean): (a: A[]) => number {
85+
var where = cfilter(pred);
86+
return compose(length2, where);
87+
~~~~~~~
88+
!!! error TS2345: Argument of type '<A>(ar: A[]) => number' is not assignable to parameter of type '(b: {}) => number'.
89+
}
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
//// [genericTypeParameterEquivalence2strict.ts]
2+
// compose :: (b->c) -> (a->b) -> (a->c)
3+
function compose<A, B, C>(f: (b: B) => C, g: (a:A) => B): (a:A) => C {
4+
return function (a:A) : C {
5+
return f(g.apply(null, a));
6+
};
7+
}
8+
9+
// forEach :: [a] -> (a -> ()) -> ()
10+
function forEach<A>(list: A[], f: (a: A, n?: number) => void ): void {
11+
for (var i = 0; i < list.length; ++i) {
12+
f(list[i], i);
13+
}
14+
}
15+
16+
// filter :: (a->bool) -> [a] -> [a]
17+
function filter<A>(f: (a: A) => boolean, ar: A[]): A[] {
18+
var ret: A[] = [];
19+
forEach(ar, (el) => {
20+
if (f(el)) {
21+
ret.push(el);
22+
}
23+
} );
24+
25+
return ret;
26+
}
27+
28+
// length :: [a] -> Num
29+
function length2<A>(ar: A[]): number {
30+
return ar.length;
31+
}
32+
33+
// curry1 :: ((a,b)->c) -> (a->(b->c))
34+
function curry1<A, B, C>(f: (a: A, b: B) => C): (ax: A) => (bx: B) => C {
35+
return function (ay: A) {
36+
return function (by: B) {
37+
return f(ay, by);
38+
};
39+
};
40+
}
41+
42+
var cfilter = curry1(filter);
43+
44+
declare function strBool(str: string): boolean
45+
const filterer = cfilter(strBool);
46+
const expectFilterer: (a: string[]) => string[] = filterer;
47+
48+
const filtered = filterer(["hello"]);
49+
const expectFiltered: string[] = filtered;
50+
51+
// compose :: (b->c) -> (a->b) -> (a->c)
52+
// length :: [a] -> Num
53+
// cfilter :: {} -> {} -> [{}]
54+
// pred :: a -> Bool
55+
// cfilter(pred) :: {} -> [{}]
56+
// length2 :: [a] -> Num
57+
// countWhere :: (a -> Bool) -> [a] -> Num
58+
59+
function countWhere_1<A>(pred: (a: A) => boolean): (a: A[]) => number {
60+
return compose(length2, cfilter(pred));
61+
}
62+
63+
function countWhere_2<A>(pred: (a: A) => boolean): (a: A[]) => number {
64+
var where = cfilter(pred);
65+
return compose(length2, where);
66+
}
67+
68+
//// [genericTypeParameterEquivalence2strict.js]
69+
"use strict";
70+
// compose :: (b->c) -> (a->b) -> (a->c)
71+
function compose(f, g) {
72+
return function (a) {
73+
return f(g.apply(null, a));
74+
};
75+
}
76+
// forEach :: [a] -> (a -> ()) -> ()
77+
function forEach(list, f) {
78+
for (var i = 0; i < list.length; ++i) {
79+
f(list[i], i);
80+
}
81+
}
82+
// filter :: (a->bool) -> [a] -> [a]
83+
function filter(f, ar) {
84+
var ret = [];
85+
forEach(ar, function (el) {
86+
if (f(el)) {
87+
ret.push(el);
88+
}
89+
});
90+
return ret;
91+
}
92+
// length :: [a] -> Num
93+
function length2(ar) {
94+
return ar.length;
95+
}
96+
// curry1 :: ((a,b)->c) -> (a->(b->c))
97+
function curry1(f) {
98+
return function (ay) {
99+
return function (by) {
100+
return f(ay, by);
101+
};
102+
};
103+
}
104+
var cfilter = curry1(filter);
105+
var filterer = cfilter(strBool);
106+
var expectFilterer = filterer;
107+
var filtered = filterer(["hello"]);
108+
var expectFiltered = filtered;
109+
// compose :: (b->c) -> (a->b) -> (a->c)
110+
// length :: [a] -> Num
111+
// cfilter :: {} -> {} -> [{}]
112+
// pred :: a -> Bool
113+
// cfilter(pred) :: {} -> [{}]
114+
// length2 :: [a] -> Num
115+
// countWhere :: (a -> Bool) -> [a] -> Num
116+
function countWhere_1(pred) {
117+
return compose(length2, cfilter(pred));
118+
}
119+
function countWhere_2(pred) {
120+
var where = cfilter(pred);
121+
return compose(length2, where);
122+
}

0 commit comments

Comments
 (0)