Skip to content
This repository has been archived by the owner on Jul 25, 2018. It is now read-only.

Commit

Permalink
feat(lens-like): support PseudoLens (lensIndex, lensProp) (#99)
Browse files Browse the repository at this point in the history
  • Loading branch information
ikatyang authored Aug 10, 2017
1 parent 0460185 commit cec493c
Show file tree
Hide file tree
Showing 31 changed files with 365 additions and 97 deletions.
6 changes: 3 additions & 3 deletions snapshots/lens.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ import * as R_lens from '../ramda/dist/src/lens';
declare const object_to_string: (x: object) => string;
declare const string_object_to_object: (x: string, y: object) => object;

// @dts-jest:pass -> (setter: (focus: string, target: object) => object) => Lens<string, object>
// @dts-jest:pass -> (setter: (focus: string, target: object) => object) => ManualLens<string, object>
R_lens(object_to_string);
// @dts-jest:pass -> Lens<string, object>
// @dts-jest:pass -> ManualLens<string, object>
R_lens(object_to_string)(string_object_to_object);
// @dts-jest:pass -> Lens<string, object>
// @dts-jest:pass -> ManualLens<string, object>
R_lens(object_to_string, string_object_to_object);
8 changes: 5 additions & 3 deletions snapshots/lensIndex.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import * as R_lensIndex from '../ramda/dist/src/lensIndex';

// @dts-jest:pass -> Lens<{}, {}[] | ArrayLike<{}>>
declare const number: number;

// @dts-jest:pass -> PseudoLens<0>
R_lensIndex(0);
// @dts-jest:pass -> Lens<number, number[]>
R_lensIndex<number, number[]>(0);
// @dts-jest:pass -> PseudoLens<number>
R_lensIndex(number);
4 changes: 2 additions & 2 deletions snapshots/lensPath.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import * as R_lensPath from '../ramda/dist/src/lensPath';

declare const path: Path;

// @dts-jest:pass -> Lens<{}, {}>
// @dts-jest:pass -> ManualLens<{}, {}>
R_lensPath(path);
// @dts-jest:pass -> Lens<object, number[]>
// @dts-jest:pass -> ManualLens<object, number[]>
R_lensPath<object, number[]>(path);
8 changes: 6 additions & 2 deletions snapshots/lensProp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@ import * as R_lensProp from '../ramda/dist/src/lensProp';

declare const property: Property;

// @dts-jest:pass -> Lens<{}, {}>
// @dts-jest:pass -> PseudoLens<1>
R_lensProp(1);
// @dts-jest:pass -> PseudoLens<"x">
R_lensProp('x');
// @dts-jest:pass -> ManualLens<{}, {}>
R_lensProp(property);
// @dts-jest:pass -> Lens<number, object>
// @dts-jest:pass -> ManualLens<number, object>
R_lensProp<number, object>(property);
34 changes: 29 additions & 5 deletions snapshots/over.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,37 @@
import { Lens } from '../ramda/dist/src/$types';
import { ManualLens, PseudoLens } from '../ramda/dist/src/$types';
import * as R_over from '../ramda/dist/src/over';

declare const number_object_lens: Lens<number, object>;
declare const menual_lens_number_object: ManualLens<number, object>;
declare const pseudo_lens_a: PseudoLens<'a'>;
declare const pseudo_lens_1: PseudoLens<1>;

declare const number_to_number: (x: number) => number;
declare const object: object;
declare const a_1_b_2_c_3: { a: 1; b: 2; c: 3 };
declare const number_array: number[];
declare const string_number_tuple: [string, number];

// @dts-jest:pass -> (target: object) => object
R_over(number_object_lens, number_to_number);
R_over(menual_lens_number_object, number_to_number);
// @dts-jest:pass -> object
R_over(number_object_lens)(number_to_number)(object);
R_over(menual_lens_number_object)(number_to_number)(object);
// @dts-jest:pass -> object
R_over(number_object_lens, number_to_number, object);
R_over(menual_lens_number_object, number_to_number, object);

// @dts-jest:pass -> (target: Record<"a", any>) => Record<"a", any>
R_over(pseudo_lens_a, number_to_number);
// @dts-jest:pass -> Record<"a", any>
R_over(pseudo_lens_a)(number_to_number)(a_1_b_2_c_3);
// @dts-jest:pass -> { a: 1; b: 2; c: 3; }
R_over(pseudo_lens_a, number_to_number, a_1_b_2_c_3);

// @dts-jest:pass -> (target: {}) => {}
R_over(pseudo_lens_1, number_to_number);
// @dts-jest:pass -> {}
R_over(pseudo_lens_1)(number_to_number)(string_number_tuple);
// @dts-jest:pass -> [string, number]
R_over(pseudo_lens_1, number_to_number, string_number_tuple);
// @dts-jest:pass -> {}
R_over(pseudo_lens_1)(number_to_number)(number_array);
// @dts-jest:pass -> number[]
R_over(pseudo_lens_1, number_to_number, number_array);
18 changes: 9 additions & 9 deletions snapshots/ramda-tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1500,17 +1500,17 @@ import * as R from '../ramda/dist/index';

// @dts-jest:group lensIndex
(() => {
const headLens = R.lensIndex<any, any[]>(0);
// @dts-jest:pass -> string
R.view<string, string[]>(headLens, ['a', 'b', 'c']); //=> 'a'
const headLens = R.lensIndex(0);
// @dts-jest:pass -> any
R.view(headLens, ['a', 'b', 'c']); //=> 'a'

// @dts-jest:pass -> string[]
R.set<string, string[]>(headLens, 'x', ['a', 'b', 'c']); //=> ['x', 'b', 'c']
R.set(headLens, 'x', ['a', 'b', 'c']); //=> ['x', 'b', 'c']
// @dts-jest:pass -> string[]
R.set(R.__, 'x', ['a', 'b', 'c'])(headLens); //=> ['x', 'b', 'c']

// @dts-jest:pass -> string[]
R.over<string, string[]>(headLens, R.toUpper, ['a', 'b', 'c']); //=> ['A', 'b', 'c']
R.over(headLens, R.toUpper, ['a', 'b', 'c']); //=> ['A', 'b', 'c']
// @dts-jest:pass -> string[]
R.over(R.__, R.toUpper, ['a', 'b', 'c'])(headLens); //=> ['A', 'b', 'c']
})();
Expand Down Expand Up @@ -2060,7 +2060,7 @@ import * as R from '../ramda/dist/index';

// @dts-jest:group over
(() => {
const headLens = R.lensIndex<string, string[]>(0);
const headLens = R.lensIndex(0);
// @dts-jest:pass -> string[]
R.over(headLens, R.toUpper, ['a', 'b', 'c']); //=> ['A', 'b', 'c']
})();
Expand Down Expand Up @@ -2604,7 +2604,7 @@ import * as R from '../ramda/dist/index';

// @dts-jest:group set
(() => {
const headLens = R.lensIndex<string, string[]>(0);
const headLens = R.lensIndex(0);
// @dts-jest:pass -> string[]
R.set(headLens, 'x', ['a', 'b', 'c']); //=> ['x', 'b', 'c']
})();
Expand Down Expand Up @@ -3192,8 +3192,8 @@ import * as R from '../ramda/dist/index';

// @dts-jest:group view
(() => {
const headLens = R.lensIndex<string, string[]>(0);
// @dts-jest:pass -> string
const headLens = R.lensIndex(0);
// @dts-jest:pass -> any
R.view(headLens, ['a', 'b', 'c']); //=> 'a'
})();

Expand Down
36 changes: 30 additions & 6 deletions snapshots/set.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,37 @@
import { Lens } from '../ramda/dist/src/$types';
import { ManualLens, PseudoLens } from '../ramda/dist/src/$types';
import * as R_set from '../ramda/dist/src/set';

declare const number_object_lens: Lens<number, object>;
declare const number: number;
declare const menual_lens_number_object: ManualLens<number, object>;
declare const pseudo_lens_a: PseudoLens<'a'>;
declare const pseudo_lens_1: PseudoLens<1>;

declare const object: object;
declare const a_1_b_2_c_3: { a: 1; b: 2; c: 3 };
declare const number_array: number[];
declare const string_number_tuple: [string, number];
declare const number: number;

// @dts-jest:pass -> (target: object) => object
R_set(number_object_lens, number);
R_set(menual_lens_number_object, number);
// @dts-jest:pass -> object
R_set(number_object_lens)(number)(object);
R_set(menual_lens_number_object)(number)(object);
// @dts-jest:pass -> object
R_set(number_object_lens, number, object);
R_set(menual_lens_number_object, number, object);

// @dts-jest:pass -> (target: Record<"a", any>) => Record<"a", any>
R_set(pseudo_lens_a, number);
// @dts-jest:pass -> Record<"a", any>
R_set(pseudo_lens_a)(number)(a_1_b_2_c_3);
// @dts-jest:pass -> { a: 1; b: 2; c: 3; }
R_set(pseudo_lens_a, number, a_1_b_2_c_3);

// @dts-jest:pass -> (target: {}) => {}
R_set(pseudo_lens_1, number);
// @dts-jest:pass -> {}
R_set(pseudo_lens_1)(number)(string_number_tuple);
// @dts-jest:pass -> [string, number]
R_set(pseudo_lens_1, number, string_number_tuple);
// @dts-jest:pass -> {}
R_set(pseudo_lens_1)(number)(number_array);
// @dts-jest:pass -> number[]
R_set(pseudo_lens_1, number, number_array);
34 changes: 29 additions & 5 deletions snapshots/view.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,36 @@
import { Lens } from '../ramda/dist/src/$types';
import { ManualLens, PseudoLens } from '../ramda/dist/src/$types';
import * as R_view from '../ramda/dist/src/view';

declare const number_object_lens: Lens<number, object>;
declare const menual_lens_number_object: ManualLens<number, object>;
declare const pseudo_lens_a: PseudoLens<'a'>;
declare const pseudo_lens_1: PseudoLens<1>;

declare const object: object;
declare const a_1_b_2_c_3: { a: 1; b: 2; c: 3 };
declare const number_array: number[];
declare const string_number_tuple: [string, number];

// @dts-jest:pass -> (target: object) => number
R_view(number_object_lens);
R_view(menual_lens_number_object);
// @dts-jest:pass -> number
R_view(number_object_lens)(object);
R_view(menual_lens_number_object)(object);
// @dts-jest:pass -> number
R_view(number_object_lens, object);
R_view(menual_lens_number_object, object);

// @dts-jest:pass -> <U extends Record<"a", any>>(target: U) => U["a"]
R_view(pseudo_lens_a);
// @dts-jest:pass -> 1
R_view(pseudo_lens_a)(a_1_b_2_c_3);
// @dts-jest:pass -> 1
R_view(pseudo_lens_a, a_1_b_2_c_3);

// @dts-jest:pass -> <U extends { [index: number]: any; }>(target: U) => U["1"][1]
R_view(pseudo_lens_1);
// @dts-jest:pass -> any
R_view(pseudo_lens_1)(string_number_tuple);
// @dts-jest:pass -> any
R_view(pseudo_lens_1, string_number_tuple);
// @dts-jest:pass -> any
R_view(pseudo_lens_1)(number_array);
// @dts-jest:pass -> any
R_view(pseudo_lens_1, number_array);
5 changes: 5 additions & 0 deletions templates/$operation.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,8 @@ export type Same<T extends string, U extends string> = Diff<
Diff<T, U> | Diff<U, T>
>;
export type Merge<T, U> = Omit<T, keyof U> & U;

// from https://github.com/tycho01/typical/blob/f0e6918/src/cast.ts#L18
// to resolve https://github.com/Microsoft/TypeScript/issues/15768
// tslint:disable-next-line
export type NumberToString = { 0:'0',1:'1',2:'2',3:'3',4:'4',5:'5',6:'6',7:'7',8:'8',9:'9',10:'10',11:'11',12:'12',13:'13',14:'14',15:'15',16:'16',17:'17',18:'18',19:'19',20:'20',21:'21',22:'22',23:'23',24:'24',25:'25',26:'26',27:'27',28:'28',29:'29',30:'30',31:'31',32:'32',33:'33',34:'34',35:'35',36:'36',37:'37',38:'38',39:'39',40:'40',41:'41',42:'42',43:'43',44:'44',45:'45',46:'46',47:'47',48:'48',49:'49',50:'50',51:'51',52:'52',53:'53',54:'54',55:'55',56:'56',57:'57',58:'58',59:'59',60:'60',61:'61',62:'62',63:'63',64:'64',65:'65',66:'66',67:'67',68:'68',69:'69',70:'70',71:'71',72:'72',73:'73',74:'74',75:'75',76:'76',77:'77',78:'78',79:'79',80:'80',81:'81',82:'82',83:'83',84:'84',85:'85',86:'86',87:'87',88:'88',89:'89',90:'90',91:'91',92:'92',93:'93',94:'94',95:'95',96:'96',97:'97',98:'98',99:'99',100:'100',101:'101',102:'102',103:'103',104:'104',105:'105',106:'106',107:'107',108:'108',109:'109',110:'110',111:'111',112:'112',113:'113',114:'114',115:'115',116:'116',117:'117',118:'118',119:'119',120:'120',121:'121',122:'122',123:'123',124:'124',125:'125',126:'126',127:'127',128:'128',129:'129',130:'130',131:'131',132:'132',133:'133',134:'134',135:'135',136:'136',137:'137',138:'138',139:'139',140:'140',141:'141',142:'142',143:'143',144:'144',145:'145',146:'146',147:'147',148:'148',149:'149',150:'150',151:'151',152:'152',153:'153',154:'154',155:'155',156:'156',157:'157',158:'158',159:'159',160:'160',161:'161',162:'162',163:'163',164:'164',165:'165',166:'166',167:'167',168:'168',169:'169',170:'170',171:'171',172:'172',173:'173',174:'174',175:'175',176:'176',177:'177',178:'178',179:'179',180:'180',181:'181',182:'182',183:'183',184:'184',185:'185',186:'186',187:'187',188:'188',189:'189',190:'190',191:'191',192:'192',193:'193',194:'194',195:'195',196:'196',197:'197',198:'198',199:'199',200:'200',201:'201',202:'202',203:'203',204:'204',205:'205',206:'206',207:'207',208:'208',209:'209',210:'210',211:'211',212:'212',213:'213',214:'214',215:'215',216:'216',217:'217',218:'218',219:'219',220:'220',221:'221',222:'222',223:'223',224:'224',225:'225',226:'226',227:'227',228:'228',229:'229',230:'230',231:'231',232:'232',233:'233',234:'234',235:'235',236:'236',237:'237',238:'238',239:'239',240:'240',241:'241',242:'242',243:'243',244:'244',245:'245',246:'246',247:'247',248:'248',249:'249',250:'250',251:'251',252:'252',253:'253',254:'254',255:'255'};
9 changes: 7 additions & 2 deletions templates/$types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,13 @@ export interface Ordered {

// ramda

export interface Lens<T, U> {
(toFunctorFn: (value: T) => Functor<T>): (target: U) => U; // tslint:disable-line:callable-types
export interface ManualLens<T, U> {
_fake_lens_getter: T;
_fake_lens_setter: U;
}

export interface PseudoLens<K extends string | number> {
_fake_lens_prop: K;
}

export interface Transformer<T, U, R> {
Expand Down
4 changes: 2 additions & 2 deletions templates/lens.d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Lens } from './$types';
import { ManualLens } from './$types';

export function $<T, U>(
getter: (target: U) => T,
setter: (focus: T, target: U) => U,
): Lens<T, U>;
): ManualLens<T, U>;
4 changes: 2 additions & 2 deletions templates/lensIndex.d.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
import { Lens, List } from './$types';
import { List, PseudoLens } from './$types';

export function $<T, U extends List<T>>(index: number): Lens<T, U>;
export function $<N extends number>(index: N): PseudoLens<N>;
4 changes: 2 additions & 2 deletions templates/lensPath.d.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
import { Lens, Path } from './$types';
import { ManualLens, Path } from './$types';

export function $<T, U>(path: Path): Lens<T, U>;
export function $<T, U>(path: Path): ManualLens<T, U>;
5 changes: 3 additions & 2 deletions templates/lensProp.d.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { Lens, Property } from './$types';
import { ManualLens, Property, PseudoLens } from './$types';

export function $<T, U>(property: Property): Lens<T, U>;
export function $key<K extends string | number>(property: K): PseudoLens<K>;
export function $general<T, U>(property: Property): ManualLens<T, U>;
24 changes: 22 additions & 2 deletions templates/over.d.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,23 @@
import { Lens, Morphism } from './$types';
import { NumberToString } from './$operation';
import { Dictionary, ManualLens, Morphism, PseudoLens } from './$types';

export function $<T, U>(lens: Lens<T, U>, fn: Morphism<T, T>, target: U): U;
export function $number<N extends number, U extends { [index: number]: any }>(
lens: PseudoLens<N>,
fn: Morphism<U[NumberToString[N]], U[NumberToString[N]]>,
target: U,
): U;
export function $string<K extends string, U extends Record<K, any>>(
lens: PseudoLens<K>,
fn: Morphism<U[K], U[K]>,
target: U,
): U;
export function $manual<T, U>(
lens: ManualLens<T, U>,
fn: Morphism<T, T>,
target: U,
): U;
export function $general<V, U>(
lens: PseudoLens<any> | ManualLens<any, U>,
fn: Morphism<V, V>,
target: U,
): U;
20 changes: 18 additions & 2 deletions templates/set.d.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
import { Lens } from './$types';
import { NumberToString } from './$operation';
import { Dictionary, ManualLens, Morphism, PseudoLens } from './$types';

export function $<T, U>(lens: Lens<T, U>, value: T, target: U): U;
export function $number<N extends number, U extends { [index: number]: any }>(
lens: PseudoLens<N>,
value: U[NumberToString[N]],
target: U,
): U;
export function $string<K extends string, U extends Record<K, any>>(
lens: PseudoLens<K>,
value: U[K],
target: U,
): U;
export function $manual<T, U>(lens: ManualLens<T, U>, value: T, target: U): U;
export function $general<U>(
lens: PseudoLens<any> | ManualLens<any, U>,
fn: any,
target: U,
): U;
17 changes: 15 additions & 2 deletions templates/view.d.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
import { Lens } from './$types';
import { NumberToString } from './$operation';
import { Dictionary, ManualLens, Morphism, PseudoLens } from './$types';

export function $<T, U>(lens: Lens<T, U>, target: U): T;
export function $number<N extends number, U extends { [index: number]: any }>(
lens: PseudoLens<N>,
target: U,
): U[NumberToString[N]];
export function $string<K extends string, U extends Record<K, any>>(
lens: PseudoLens<K>,
target: U,
): U[K];
export function $manual<T, U>(lens: ManualLens<T, U>, target: U): T;
export function $general<T, U>(
lens: PseudoLens<any> | ManualLens<T, U>,
target: U,
): T | U[any];
6 changes: 3 additions & 3 deletions tests/__snapshots__/lens.ts.snap
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`R_lens(object_to_string) 1`] = `"(setter: (focus: string, target: object) => object) => Lens<string, object>"`;
exports[`R_lens(object_to_string) 1`] = `"(setter: (focus: string, target: object) => object) => ManualLens<string, object>"`;

exports[`R_lens(object_to_string)(string_object_to_object) 1`] = `"Lens<string, object>"`;
exports[`R_lens(object_to_string)(string_object_to_object) 1`] = `"ManualLens<string, object>"`;

exports[`R_lens(object_to_string, string_object_to_object) 1`] = `"Lens<string, object>"`;
exports[`R_lens(object_to_string, string_object_to_object) 1`] = `"ManualLens<string, object>"`;
4 changes: 2 additions & 2 deletions tests/__snapshots__/lensIndex.ts.snap
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`R_lensIndex(0) 1`] = `"Lens<{}, {}[] | ArrayLike<{}>>"`;
exports[`R_lensIndex(0) 1`] = `"PseudoLens<0>"`;

exports[`R_lensIndex<number, number[]>(0) 1`] = `"Lens<number, number[]>"`;
exports[`R_lensIndex(number) 1`] = `"PseudoLens<number>"`;
4 changes: 2 additions & 2 deletions tests/__snapshots__/lensPath.ts.snap
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`R_lensPath(path) 1`] = `"Lens<{}, {}>"`;
exports[`R_lensPath(path) 1`] = `"ManualLens<{}, {}>"`;

exports[`R_lensPath<object, number[]>(path) 1`] = `"Lens<object, number[]>"`;
exports[`R_lensPath<object, number[]>(path) 1`] = `"ManualLens<object, number[]>"`;
8 changes: 6 additions & 2 deletions tests/__snapshots__/lensProp.ts.snap
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`R_lensProp(property) 1`] = `"Lens<{}, {}>"`;
exports[`R_lensProp('x') 1`] = `"PseudoLens<\\"x\\">"`;

exports[`R_lensProp<number, object>(property) 1`] = `"Lens<number, object>"`;
exports[`R_lensProp(1) 1`] = `"PseudoLens<1>"`;

exports[`R_lensProp(property) 1`] = `"ManualLens<{}, {}>"`;

exports[`R_lensProp<number, object>(property) 1`] = `"ManualLens<number, object>"`;
Loading

0 comments on commit cec493c

Please sign in to comment.