Skip to content

Instantly share code, notes, and snippets.

@shuhei
Last active September 4, 2017 14:53
Show Gist options
  • Save shuhei/dcf8d73240d5352dcdab5f1c612a3bff to your computer and use it in GitHub Desktop.
Save shuhei/dcf8d73240d5352dcdab5f1c612a3bff to your computer and use it in GitHub Desktop.
Sketch of JSON Decoder in JavaScript
declare opaque type Decoder<T>;
declare var num: Decoder<number>;
declare var str: Decoder<string>;
declare var bool: Decoder<boolean>;
declare function array<T>(decoder: Decoder<T>): Decoder<T[]>;
declare function field<T>(key: string, decoder: Decoder<T>): Decoder<T>;
declare function nullable<T>(decoder: Decoder<T>): Decoder<?T>;
declare function maybe<T>(decoder: Decoder<T>): Decoder<?T>;
declare function at<T>(keys: string[], decoder: Decoder<T>): Decoder<T>;
declare function oneOf<T>(decoders: Decoder<T>[]): Decoder<T>;
declare function succeed<T>(value: T): Decoder<T>;
declare function fail<T>(error: string): Decoder<T>;
declare function nul<T>(defaultValue: T): Decoder<T>;
declare function andThen<A, B>(f: (A) => Decoder<B>, Decoder<A>): Decoder<B>;
declare function map<A, T>(
tagger: (A) => T,
a: Decoder<A>,
): Decoder<T>;
declare function map2<A, B, T>(
tagger: (A, B) => T,
a: Decoder<A>,
b: Decoder<B>,
): Decoder<T>;
declare function map3<A, B, C, T>(
tagger: (A, B) => T,
a: Decoder<A>,
b: Decoder<B>,
c: Decoder<C>,
): Decoder<T>;
declare function decodeString<T>(decoder: Decoder<T>, json: string): Promise<T>;
declare function decodeValue<T>(decoder: Decoder<T>, value: any): Promise<T>;
type Parent = {
name: string,
children: Child[],
};
type Child = {
name: string,
};
const childDecoder = map(
(name) => ({ name }),
filed('name', str),
);
const parentDecoder = map2(
(name, children) => ({ name, children }),
field('name', str),
filed('children', array(childDecoder)),
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment