{"action":"created","issue":{"url":"https://api.github.com/repos/Microsoft/TypeScript/issues/1213","repository_url":"https://api.github.com/repos/Microsoft/TypeScript","labels_url":"https://api.github.com/repos/Microsoft/TypeScript/issues/1213/labels{/name}","comments_url":"https://api.github.com/repos/Microsoft/TypeScript/issues/1213/comments","events_url":"https://api.github.com/repos/Microsoft/TypeScript/issues/1213/events","html_url":"https://github.com/Microsoft/TypeScript/issues/1213","id":49436743,"number":1213,"title":"Allow classes to be parametric in other parametric classes","user":{"login":"metaweta","id":857592,"avatar_url":"https://avatars.githubusercontent.com/u/857592?v=3","gravatar_id":"","url":"https://api.github.com/users/metaweta","html_url":"https://github.com/metaweta","followers_url":"https://api.github.com/users/metaweta/followers","following_url":"https://api.github.com/users/metaweta/following{/other_user}","gists_url":"https://api.github.com/users/metaweta/gists{/gist_id}","starred_url":"https://api.github.com/users/metaweta/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/metaweta/subscriptions","organizations_url":"https://api.github.com/users/metaweta/orgs","repos_url":"https://api.github.com/users/metaweta/repos","events_url":"https://api.github.com/users/metaweta/events{/privacy}","received_events_url":"https://api.github.com/users/metaweta/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/Microsoft/TypeScript/labels/Accepting%20PRs","name":"Accepting PRs","color":"009800"},{"url":"https://api.github.com/repos/Microsoft/TypeScript/labels/Suggestion","name":"Suggestion","color":"006b75"}],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":{"url":"https://api.github.com/repos/Microsoft/TypeScript/milestones/2","html_url":"https://github.com/Microsoft/TypeScript/milestones/Community","labels_url":"https://api.github.com/repos/Microsoft/TypeScript/milestones/2/labels","id":721044,"number":2,"title":"Community","description":"Issues in the 'Community' milestone are ones which we are accepting pull requests for","creator":{"login":"RyanCavanaugh","id":6685088,"avatar_url":"https://avatars.githubusercontent.com/u/6685088?v=3","gravatar_id":"","url":"https://api.github.com/users/RyanCavanaugh","html_url":"https://github.com/RyanCavanaugh","followers_url":"https://api.github.com/users/RyanCavanaugh/followers","following_url":"https://api.github.com/users/RyanCavanaugh/following{/other_user}","gists_url":"https://api.github.com/users/RyanCavanaugh/gists{/gist_id}","starred_url":"https://api.github.com/users/RyanCavanaugh/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/RyanCavanaugh/subscriptions","organizations_url":"https://api.github.com/users/RyanCavanaugh/orgs","repos_url":"https://api.github.com/users/RyanCavanaugh/repos","events_url":"https://api.github.com/users/RyanCavanaugh/events{/privacy}","received_events_url":"https://api.github.com/users/RyanCavanaugh/received_events","type":"User","site_admin":false},"open_issues":197,"closed_issues":94,"state":"open","created_at":"2014-07-14T23:24:58Z","updated_at":"2016-08-02T03:44:30Z","due_on":null,"closed_at":null},"comments":25,"created_at":"2014-11-19T18:46:02Z","updated_at":"2016-08-02T17:43:20Z","closed_at":null,"body":"This is a proposal for allowing generics as type parameters.  It's currently possible to write specific examples of monads, but in order to write the interface that all monads satisfy, I propose writing\r\n```javascript\r\ninterface Monad<T<~>> {\r\n  map<A, B>(f: (a: A) => B): T<A> => T<B>;\r\n  lift<A>(a: A): T<A>;\r\n  join<A>(tta: T<T<A>>): T<A>;\r\n}\r\n```\r\nSimilarly, it's possible to write specific examples of cartesian functors, but in order to write the interface that all cartesian functors satisfy, I propose writing\r\n```javascript\r\ninterface Cartesian<T<~>> {\r\n  all<A>(a: Array<T<A>>): T<Array<A>>;\r\n}\r\n```\r\nParametric type parameters can take any number of arguments:\r\n```javascript\r\ninterface Foo<T<~,~>> {\r\n  bar<A, B>(f: (a: A) => B): T<A, B>;\r\n}\r\n```\r\nThat is, when a type parameter is followed by a tilde and a natural arity, the type parameter should be allowed to be used as a generic type with the given arity in the rest of the declaration.\r\n\r\nJust as is the case now, when implementing such an interface, the generic type parameters should be filled in:\r\n```javascript\r\nclass ArrayMonad<A> implements Monad<Array> {\r\n  map<A, B>(f: (a:A) => B): Array<A> => Array<B> {\r\n    return (arr: Array<A>) =>  arr.map(f);\r\n  }\r\n  lift<A>(a: A): Array<A> { return [a]; }\r\n  join<A>(tta: Array<Array<A>>): Array<A> {\r\n    return tta.reduce((prev, cur) => prev.concat(cur));\r\n  }\r\n}\r\n```\r\n\r\nIn addition to directly allowing compositions of generic types in the arguments, I propose that typedefs also support defining generics in this way (see [issue 308](https://github.com/Microsoft/TypeScript/issues/308)):\r\n```javascript\r\ntypedef Maybe<Array<~>> Composite<~> ;\r\nclass Foo implements Monad<Composite<~>> { ... }\r\n```\r\nThe arities of the definition and the alias must match for the typedef to be valid.\r\n\r\n"},"comment":{"url":"https://api.github.com/repos/Microsoft/TypeScript/issues/comments/236983176","html_url":"https://github.com/Microsoft/TypeScript/issues/1213#issuecomment-236983176","issue_url":"https://api.github.com/repos/Microsoft/TypeScript/issues/1213","id":236983176,"user":{"login":"paldepind","id":521604,"avatar_url":"https://avatars.githubusercontent.com/u/521604?v=3","gravatar_id":"","url":"https://api.github.com/users/paldepind","html_url":"https://github.com/paldepind","followers_url":"https://api.github.com/users/paldepind/followers","following_url":"https://api.github.com/users/paldepind/following{/other_user}","gists_url":"https://api.github.com/users/paldepind/gists{/gist_id}","starred_url":"https://api.github.com/users/paldepind/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/paldepind/subscriptions","organizations_url":"https://api.github.com/users/paldepind/orgs","repos_url":"https://api.github.com/users/paldepind/repos","events_url":"https://api.github.com/users/paldepind/events{/privacy}","received_events_url":"https://api.github.com/users/paldepind/received_events","type":"User","site_admin":false},"created_at":"2016-08-02T17:43:20Z","updated_at":"2016-08-02T17:43:20Z","body":"I think this proposal is absolutely wonderful. Having higher kinded types in TypeScript would take it up to a hole new level where we could describe more powerful abstractions than what is currently possible.\r\n\r\nHowever, isn't there something wrong with the examples given in OP? The `A` in the line \r\n\r\n```\r\nclass ArrayMonad<A> implements Monad<Array> {\r\n```\r\n\r\nisn't used in any of the methods, since they all have their own generic `A`.\r\n\r\nAlso, if implementing functor with `map` as a method that uses `this` what would it look like? Like this maybe?\r\n\r\n```typescript\r\ninterface Functor<T, A> {\r\n  map<B>(f: (a: A) => B): T<A> => T<B>;\r\n}\r\n\r\nclass Maybe<A> implements Functor<Maybe, A> {\r\n  ...\r\n}\r\n```"}}
{"actor":{"display_login":"paldepind"}}