{"action":"created","issue":{"url":"https://api.github.com/repos/SimonMeskens/TypeProps/issues/1","repository_url":"https://api.github.com/repos/SimonMeskens/TypeProps","labels_url":"https://api.github.com/repos/SimonMeskens/TypeProps/issues/1/labels{/name}","comments_url":"https://api.github.com/repos/SimonMeskens/TypeProps/issues/1/comments","events_url":"https://api.github.com/repos/SimonMeskens/TypeProps/issues/1/events","html_url":"https://github.com/SimonMeskens/TypeProps/issues/1","id":315717933,"number":1,"title":"Sample case by Asad Saeeduddin","user":{"login":"SimonMeskens","id":4284735,"avatar_url":"https://avatars2.githubusercontent.com/u/4284735?v=4","gravatar_id":"","url":"https://api.github.com/users/SimonMeskens","html_url":"https://github.com/SimonMeskens","followers_url":"https://api.github.com/users/SimonMeskens/followers","following_url":"https://api.github.com/users/SimonMeskens/following{/other_user}","gists_url":"https://api.github.com/users/SimonMeskens/gists{/gist_id}","starred_url":"https://api.github.com/users/SimonMeskens/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/SimonMeskens/subscriptions","organizations_url":"https://api.github.com/users/SimonMeskens/orgs","repos_url":"https://api.github.com/users/SimonMeskens/repos","events_url":"https://api.github.com/users/SimonMeskens/events{/privacy}","received_events_url":"https://api.github.com/users/SimonMeskens/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":8,"created_at":"2018-04-19T03:47:00Z","updated_at":"2018-04-19T23:48:44Z","closed_at":null,"author_association":"OWNER","body":"@masaeedu\r\n\r\ntypeprops.ts:\r\n```ts\r\ntype defined = {} | null;\r\ntype unknown = {} | null | undefined;\r\n\r\ntype Tuple = {\r\n    [index: number]: unknown;\r\n    length: number;\r\n};\r\n\r\ndeclare module \"typeprops\" {\r\n    interface TypeProps<Type, Params extends Tuple = never> {\r\n        never: {\r\n            parameters: never;\r\n            type: never;\r\n        };\r\n    }\r\n\r\n    type TypeParams<T> = TypeProps<T>[keyof TypeProps<T>][\"parameters\"];\r\n\r\n    type Generic<T, Params extends Tuple = TypeParams<T>> = TypeProps<\r\n        T,\r\n        Params\r\n    >[keyof TypeProps<T>][\"type\"];\r\n}\r\n```\r\n\r\nmaybe.ts:\r\n```ts\r\nimport { Generic } from \"typeprops\";\r\n\r\ninterface GenericMaybe<F> {\r\n    of: <T>(x: T) => Generic<F, [T]>;\r\n    map: <T, U>(f: (a: T) => U) => (o: Generic<F, [T]>) => Generic<F, [U]>;\r\n    chain: <T, U>(\r\n        f: (a: T) => Generic<F, [U]>\r\n    ) => (o: Generic<F, [T]>) => Generic<F, [U]>;\r\n}\r\n\r\ninterface GenericMatch<F> {\r\n    <T, U>(\r\n        o: {\r\n            Map: (x: T) => Generic<F, [U]>;\r\n            None: Generic<F, [undefined]>;\r\n        }\r\n    ): (o: Generic<F, [T]>) => Generic<F, [U]>;\r\n}\r\n\r\n// Just :: a -> T a\r\n// None :: T a\r\n// match :: { \"Just\" :: a -> b, \"None\" :: b } -> T a -> b\r\nconst GenericMaybe = <F>({\r\n    Just,\r\n    None,\r\n    match\r\n}: {\r\n    Just: <T>(x: T) => Generic<F, [T]>;\r\n    None: F;\r\n    match: GenericMatch<F>;\r\n}): GenericMaybe<F> => {\r\n    const genericNone = (None as any) as Generic<F, [undefined]>;\r\n\r\n    // Functor\r\n    // map :: (a -> b) -> T a -> T b\r\n    const map = <T, U>(f: (a: T) => U) =>\r\n        match!({ None: genericNone, Map: (x: T) => Just(f(x)) });\r\n\r\n    // Monad\r\n    // of :: a -> T a\r\n    const of = Just;\r\n    // chain :: (a -> T b) -> T a -> T b\r\n    const chain = <T, U>(f: (a: T) => Generic<F, [U]>) =>\r\n        match!({ None: genericNone, Map: f });\r\n\r\n    return { map, of, chain };\r\n};\r\n\r\n// A possible representation of a Maybe\r\nconst k = Symbol(\"my maybe key\");\r\ntype Maybe<T> = { [k]: T | undefined };\r\n\r\ndeclare module \"typeprops\" {\r\n    interface TypeProps<Type, Params extends Tuple = never> {\r\n        [k]: {\r\n            parameters: Type extends Maybe<infer A> ? [A] : never;\r\n            type: Type extends Maybe<any> ? Maybe<Params[0]> : never;\r\n        };\r\n    }\r\n}\r\n\r\nconst Just = <T>(x: T) => ({ [k]: x } as Maybe<T>);\r\nconst None = {} as Maybe<undefined>;\r\n\r\nconst match: <T, U>(\r\n    {\r\n        Map,\r\n        None\r\n    }: {\r\n        Map: (x: T) => Maybe<U>;\r\n        None: Maybe<undefined>;\r\n    }\r\n) => (o: Maybe<T>) => Maybe<U> = <T, U>({\r\n    Map,\r\n    None\r\n}: {\r\n    Map: (x: T) => Maybe<U>;\r\n    None: Maybe<undefined>;\r\n}) => (o: Maybe<T>) => (o.hasOwnProperty(k) ? Map(o[k]!) : None) as Maybe<U>;\r\n\r\nconst { map, chain, of } = GenericMaybe({ Just, None, match });\r\n\r\n// Examples\r\nconsole.log([\r\n    map((x: number) => x + 2)(of(42)),\r\n    map((x: number) => x + 2)(None),\r\n    chain((x: number) => (x > 40 ? None : of(x * 2)) as Maybe<number>)(of(42)),\r\n    chain((x: number) => (x > 40 ? None : of(x * 2)) as Maybe<number>)(of(32)),\r\n    map((x: number) => None)(of(42)),\r\n    map((x: number) => of(x * 2))(of(42))\r\n]);\r\n```\r\n\r\nPlayground: [Playground link](https://www.typescriptlang.org/play/#src=type%20defined%20%3D%20%7B%7D%20%7C%20null%3B%0D%0Atype%20unknown%20%3D%20%7B%7D%20%7C%20null%20%7C%20undefined%3B%0D%0A%0D%0Atype%20Tuple%20%3D%20%7B%0D%0A%20%20%5Bindex%3A%20number%5D%3A%20unknown%3B%0D%0A%20%20length%3A%20number%3B%0D%0A%7D%3B%0D%0A%0D%0Ainterface%20TypeProps%3CType%2C%20Params%20extends%20Tuple%20%3D%20never%3E%20%7B%0D%0A%20%20never%3A%20%7B%0D%0A%20%20%20%20parameters%3A%20never%3B%0D%0A%20%20%20%20type%3A%20never%3B%0D%0A%20%20%7D%3B%0D%0A%7D%0D%0A%0D%0Atype%20TypeParams%3CT%3E%20%3D%20TypeProps%3CT%3E%5Bkeyof%20TypeProps%3CT%3E%5D%5B%22parameters%22%5D%3B%0D%0A%0D%0Atype%20Generic%3CT%2C%20Params%20extends%20Tuple%20%3D%20TypeParams%3CT%3E%3E%20%3D%20TypeProps%3CT%2C%20Params%3E%5Bkeyof%20TypeProps%3CT%3E%5D%5B%22type%22%5D%3B%0D%0A%0D%0A%0D%0A%2F%2F%20Just%20%3A%3A%20a%20-%3E%20T%20a%0D%0A%2F%2F%20None%20%3A%3A%20T%20a%0D%0A%2F%2F%20match%20%3A%3A%20%7B%20%22Just%22%20%3A%3A%20a%20-%3E%20b%2C%20%22None%22%20%3A%3A%20b%20%7D%20-%3E%20T%20a%20-%3E%20b%0D%0Aconst%20GenericMaybe%20%3D%20%3CF%3E(%7B%0D%0A%20%20Just%2C%0D%0A%20%20None%2C%0D%0A%20%20match%0D%0A%7D%3A%20%7B%0D%0A%20%20%20%20Just%3A%20%3CT%3E(x%3A%20T)%20%3D%3E%20Generic%3CF%2C%20%5BT%5D%3E%3B%0D%0A%20%20%20%20None%3A%20F%3B%0D%0A%20%20%20%20match%3A%20%3CT%2C%20U%3E(%0D%0A%20%20%20%20%20%20%7B%0D%0A%20%20%20%20%20%20%20%20Map%2C%0D%0A%20%20%20%20%20%20%20%20None%0D%0A%20%20%20%20%20%20%7D%3A%20%7B%0D%0A%20%20%20%20%20%20%20%20%20%20Map%3A%20(x%3A%20T)%20%3D%3E%20Generic%3CF%2C%20%5BU%5D%3E%3B%0D%0A%20%20%20%20%20%20%20%20%20%20None%3A%20Generic%3CF%2C%20%5Bundefined%5D%3E%3B%0D%0A%20%20%20%20%20%20%20%20%7D%0D%0A%20%20%20%20)%20%3D%3E%20(o%3A%20Generic%3CF%2C%20%5BT%5D%3E)%20%3D%3E%20Generic%3CF%2C%20%5BU%5D%3E%3B%0D%0A%20%20%7D)%20%3D%3E%20%7B%0D%0A%20%20const%20genericNone%20%3D%20(None%20as%20any)%20as%20Generic%3CF%2C%20%5Bundefined%5D%3E%3B%0D%0A%0D%0A%20%20%2F%2F%20Functor%0D%0A%20%20%2F%2F%20map%20%3A%3A%20(a%20-%3E%20b)%20-%3E%20T%20a%20-%3E%20T%20b%0D%0A%20%20const%20map%20%3D%20%3CT%2C%20U%3E(f%3A%20(a%3A%20T)%20%3D%3E%20U)%20%3D%3E%0D%0A%20%20%20%20match!(%7B%20None%3A%20genericNone%2C%20Map%3A%20(x%3A%20T)%20%3D%3E%20Just(f(x))%20%7D)%3B%0D%0A%0D%0A%20%20%2F%2F%20Monad%0D%0A%20%20%2F%2F%20of%20%3A%3A%20a%20-%3E%20T%20a%0D%0A%20%20const%20of%20%3D%20Just%3B%0D%0A%20%20%2F%2F%20chain%20%3A%3A%20(a%20-%3E%20T%20b)%20-%3E%20T%20a%20-%3E%20T%20b%0D%0A%20%20const%20chain%20%3D%20%3CT%2C%20U%3E(f%3A%20(a%3A%20T)%20%3D%3E%20Generic%3CF%2C%20%5BU%5D%3E)%20%3D%3E%0D%0A%20%20%20%20match!(%7B%20None%3A%20genericNone%2C%20Map%3A%20f%20%7D)%3B%0D%0A%0D%0A%20%20return%20%7B%20map%2C%20of%2C%20chain%20%7D%3B%0D%0A%7D%3B%0D%0A%0D%0A%2F%2F%20A%20possible%20representation%20of%20a%20Maybe%0D%0Aconst%20k%20%3D%20Symbol(%22my%20maybe%20key%22)%3B%0D%0Atype%20Maybe%3CT%3E%20%3D%20%7B%20%5Bk%5D%3A%20T%20%7C%20undefined%20%7D%3B%0D%0A%0D%0Ainterface%20TypeProps%3CType%2C%20Params%20extends%20Tuple%20%3D%20never%3E%20%7B%0D%0A%20%20%5Bk%5D%3A%20%7B%0D%0A%20%20%20%20parameters%3A%20Type%20extends%20Maybe%3Cinfer%20A%3E%20%3F%20%5BA%5D%20%3A%20never%3B%0D%0A%20%20%20%20type%3A%20Type%20extends%20Maybe%3Cany%3E%20%3F%20Maybe%3CParams%5B0%5D%3E%20%3A%20never%3B%0D%0A%20%20%7D%3B%0D%0A%7D%0D%0A%0D%0Aconst%20Just%20%3D%20%3CT%3E(x%3A%20T)%20%3D%3E%20(%7B%20%5Bk%5D%3A%20x%20%7D%20as%20Maybe%3CT%3E)%3B%0D%0Aconst%20None%20%3D%20%7B%7D%20as%20Maybe%3Cundefined%3E%3B%0D%0A%0D%0Aconst%20match%3A%20%3CT%2C%20U%3E(%0D%0A%20%20%7B%0D%0A%20%20%20%20Map%2C%0D%0A%20%20%20%20None%0D%0A%20%20%7D%3A%20%7B%0D%0A%20%20%20%20%20%20Map%3A%20(x%3A%20T)%20%3D%3E%20Maybe%3CU%3E%3B%0D%0A%20%20%20%20%20%20None%3A%20Maybe%3Cundefined%3E%3B%0D%0A%20%20%20%20%7D%0D%0A)%20%3D%3E%20(o%3A%20Maybe%3CT%3E)%20%3D%3E%20Maybe%3CU%3E%20%3D%20%3CT%2C%20U%3E(%7B%0D%0A%20%20Map%2C%0D%0A%20%20None%0D%0A%7D%3A%20%7B%0D%0A%20%20%20%20Map%3A%20(x%3A%20T)%20%3D%3E%20Maybe%3CU%3E%3B%0D%0A%20%20%20%20None%3A%20Maybe%3Cundefined%3E%3B%0D%0A%20%20%7D)%20%3D%3E%20(o%3A%20Maybe%3CT%3E)%20%3D%3E%20(o.hasOwnProperty(k)%20%3F%20Map(o%5Bk%5D!)%20%3A%20None)%20as%20Maybe%3CU%3E%3B%0D%0A%0D%0Aconst%20%7B%20map%2C%20chain%2C%20of%20%7D%20%3D%20GenericMaybe(%7B%20Just%2C%20None%2C%20match%20%7D)%3B%0D%0A%0D%0A%2F%2F%20Examples%0D%0Aconsole.log(%5B%0D%0A%20%20map((x%3A%20number)%20%3D%3E%20x%20%2B%202)(of(42))%2C%0D%0A%20%20map((x%3A%20number)%20%3D%3E%20x%20%2B%202)(None)%2C%0D%0A%20%20chain((x%3A%20number)%20%3D%3E%20(x%20%3E%2040%20%3F%20None%20%3A%20of(x%20*%202))%20as%20Maybe%3Cnumber%3E)(of(42))%2C%0D%0A%20%20chain((x%3A%20number)%20%3D%3E%20(x%20%3E%2040%20%3F%20None%20%3A%20of(x%20*%202))%20as%20Maybe%3Cnumber%3E)(of(32))%2C%0D%0A%20%20map((x%3A%20number)%20%3D%3E%20None)(of(42))%2C%0D%0A%20%20map((x%3A%20number)%20%3D%3E%20of(x%20*%202))(of(42))%0D%0A%5D)%3B)"},"comment":{"url":"https://api.github.com/repos/SimonMeskens/TypeProps/issues/comments/382915899","html_url":"https://github.com/SimonMeskens/TypeProps/issues/1#issuecomment-382915899","issue_url":"https://api.github.com/repos/SimonMeskens/TypeProps/issues/1","id":382915899,"user":{"login":"masaeedu","id":3674056,"avatar_url":"https://avatars1.githubusercontent.com/u/3674056?v=4","gravatar_id":"","url":"https://api.github.com/users/masaeedu","html_url":"https://github.com/masaeedu","followers_url":"https://api.github.com/users/masaeedu/followers","following_url":"https://api.github.com/users/masaeedu/following{/other_user}","gists_url":"https://api.github.com/users/masaeedu/gists{/gist_id}","starred_url":"https://api.github.com/users/masaeedu/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/masaeedu/subscriptions","organizations_url":"https://api.github.com/users/masaeedu/orgs","repos_url":"https://api.github.com/users/masaeedu/repos","events_url":"https://api.github.com/users/masaeedu/events{/privacy}","received_events_url":"https://api.github.com/users/masaeedu/received_events","type":"User","site_admin":false},"created_at":"2018-04-19T23:48:44Z","updated_at":"2018-04-19T23:48:44Z","author_association":"NONE","body":"Regarding `const chain = f => match({ None, Just: f })`, here's the type signatures of `chain` and `match` side by side:\r\n\r\n```\r\n// chain :: (a -> T b) -> T a -> T b\r\n// match :: { \"Just\" :: c -> d, \"None\" :: d } -> T c -> d\r\n```\r\n\r\nInstantiate `match` with  `c -> d` set to `a -> T b` and `d` set to `T b` (since we're passing `Just: f` and `None: None`) and you'll get `match({ None, Just: f }) :: Ta -> T b`. So overall the expression `f => match({ None, Just: f })` has the correct type signature: `(a -> T b) -> T a -> T b`."}}
{"actor":{"display_login":"masaeedu"}}