{"action":"created","issue":{"url":"https://api.github.com/repos/fantasyland/fantasy-land/issues/88","labels_url":"https://api.github.com/repos/fantasyland/fantasy-land/issues/88/labels{/name}","comments_url":"https://api.github.com/repos/fantasyland/fantasy-land/issues/88/comments","events_url":"https://api.github.com/repos/fantasyland/fantasy-land/issues/88/events","html_url":"https://github.com/fantasyland/fantasy-land/issues/88","id":57274628,"number":88,"title":"Why can `of` be defined on the constructor?","user":{"login":"CrossEye","id":151263,"avatar_url":"https://avatars.githubusercontent.com/u/151263?v=3","gravatar_id":"","url":"https://api.github.com/users/CrossEye","html_url":"https://github.com/CrossEye","followers_url":"https://api.github.com/users/CrossEye/followers","following_url":"https://api.github.com/users/CrossEye/following{/other_user}","gists_url":"https://api.github.com/users/CrossEye/gists{/gist_id}","starred_url":"https://api.github.com/users/CrossEye/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/CrossEye/subscriptions","organizations_url":"https://api.github.com/users/CrossEye/orgs","repos_url":"https://api.github.com/users/CrossEye/repos","events_url":"https://api.github.com/users/CrossEye/events{/privacy}","received_events_url":"https://api.github.com/users/CrossEye/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":3,"created_at":"2015-02-11T04:11:10Z","updated_at":"2015-02-11T12:06:30Z","closed_at":null,"body":"It's quite possible that I'm simply missing something simple, but I'm disturbed by this sentence (emphasis added):\r\n\r\n> A value which has an Applicative must provide an `of` method on itself **or** its `constructor` object.\r\n\r\n(All the same points will apply to Monoid's `empty` method, but it's Applicatives which are worrying me now.)\r\n\r\nFor a specification which is usually so prescriptive, this is surprisingly lax.  But that's not the real problem.  It seems to me that this makes it tremendously more difficult to write code that works across all Applicative Types; in fact, it probably makes it impossible.\r\n\r\nA few points:\r\n\r\n  * First of all, the Applicative laws, and Monad's _left identity_ are written only in terms of the instance version of `of`.  Should the specification be taken to read, for instance, \"The appropriate one of `m.of(a).chain(f)` or `m.constructor.of(a).chain(f)` is equivalent to `f(a)` (left identity)\" or some more precise version of the same?\r\n\r\n  * It makes unwarranted assumptions about how I create types.  In these days of `Object.create`, why should the specification assume that I use constructor functions to define my types?  It's quite possible to do without them, and it's growing ever more popular to work that way.\r\n\r\n  * It is possibly incoherent.  Since nothing specifies _which_ of the two I must implement, I can choose to implement the same `of` on both.  This would probably not cause an issue.  But nothing in the specification would prevent me from creating a conforming `of` on the instances and an unrelated `of` on the constructor or vice versa:\r\n\r\n```javascript\r\n    Maybe.of = function(val) {return new Just(val);};\r\n    Maybe.prototype.of = function(val) {throw \"Unknown Preposition\";};\r\n```\r\n\r\nDoes that conform to the specification as written so long as `Maybe.of` upholds the required laws?\r\n\r\nDoes this one so long as `Maybe.prototype.of` upholds the laws?:\r\n\r\n```javascript\r\n    Maybe.of = function(val) {throw \"Unknown Preposition\";};\r\n    Maybe.prototype.of = function(val) {return new Just(val);};\r\n```\r\n\r\nIf so, can anyone suggest a way that I can generically apply `of` to algebraic types without knowing for each specific type which version is being used?\r\n\r\nOr... am I just missing something simple again? \r\n\r\nThis was all brought to mind by a [recent Ramda issue][ri].\r\n\r\n\r\n  [ri]: https://github.com/ramda/ramda/pull/784\r\n"},"comment":{"url":"https://api.github.com/repos/fantasyland/fantasy-land/issues/comments/73871210","html_url":"https://github.com/fantasyland/fantasy-land/issues/88#issuecomment-73871210","issue_url":"https://api.github.com/repos/fantasyland/fantasy-land/issues/88","id":73871210,"user":{"login":"bergus","id":1146478,"avatar_url":"https://avatars.githubusercontent.com/u/1146478?v=3","gravatar_id":"","url":"https://api.github.com/users/bergus","html_url":"https://github.com/bergus","followers_url":"https://api.github.com/users/bergus/followers","following_url":"https://api.github.com/users/bergus/following{/other_user}","gists_url":"https://api.github.com/users/bergus/gists{/gist_id}","starred_url":"https://api.github.com/users/bergus/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bergus/subscriptions","organizations_url":"https://api.github.com/users/bergus/orgs","repos_url":"https://api.github.com/users/bergus/repos","events_url":"https://api.github.com/users/bergus/events{/privacy}","received_events_url":"https://api.github.com/users/bergus/received_events","type":"User","site_admin":false},"created_at":"2015-02-11T12:06:30Z","updated_at":"2015-02-11T12:06:30Z","body":"I would propose that all type functions need to (only) be available as methods, on the instances. That's how the laws are specified, and that's how libraries will use them - as without instances, there is no type information in js.\r\nMethods that do not need to inspect a value (like `of` and `empty`) must not rely on the `this` value, so that they can be passed around freely. This will be required for functions that want to create values with only knowing a \"type\".\r\nSuch methods should also be available as static functions (e.g. on the constructor of a class), so that they can be accessed directly (without an instance) when the expected type is known.\r\n\r\nThis way, we also won't get any problems with name collisions. Functions implement monads? Even when all constructor functions inherit an `of` method, that doesn't make their class instances applicatives."}}