{"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":4,"created_at":"2015-02-11T04:11:10Z","updated_at":"2015-02-11T13:25:17Z","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/73880055","html_url":"https://github.com/fantasyland/fantasy-land/issues/88#issuecomment-73880055","issue_url":"https://api.github.com/repos/fantasyland/fantasy-land/issues/88","id":73880055,"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},"created_at":"2015-02-11T13:25:17Z","updated_at":"2015-02-11T13:25:17Z","body":"@michaelficarra: It's not that I think that attaching to a constructor function is nonsensical.  It's the requirement to do so that seems nonsensical.  There are good ways in Javascript to create types that do not depend on constructor functions.  I believe this would be a legitimate version of `Id` with no constructor at all:\r\n\r\n```javascript\r\nvar makeId = (function() {\r\n    var baseId = {\r\n        equals: function(b) { // Setoid\r\n            return typeof this.value.equals === \"function\" ? this.value.equals(b.value) : this.value === b.value;\r\n        },\r\n        concat: function(b) { // Semigroup (value must also be a Semigroup)\r\n            return makeId(this.value.concat(b.value));\r\n        },\r\n        empty: function() { // Monoid (value must also be a Monoid)\r\n            return makeId(this.value.empty ? this.value.empty() : this.value.constructor.empty());\r\n        },\r\n        map: function(f) { // Functor\r\n            return makeId(f(this.value));\r\n        },\r\n        ap: function(b) { // Applicative\r\n            return makeId(this.value(b.value));\r\n        },\r\n        chain: function(f) { // Chain\r\n            return f(this.value);\r\n        },\r\n        extend: function(f) { // Extend\r\n            return makeId(f(this));\r\n        },\r\n        of: function(a) { //Monad\r\n            return makeId(a);\r\n        },\r\n        from: function() { // Comonad\r\n            return this.value;\r\n        }\r\n    };\r\n\r\n    function makeId(a) {\r\n        var id = Object.create(baseId);\r\n        id.value = a;\r\n        return id;\r\n    }\r\n    return makeId;\r\n}());\r\n```\r\n\r\nThe prototypes of `makeId('a')` and `makeId('b')` are identical, which is really what is meant in Javascript for two things to be of the same type.  But there is no useful constructor function around.  (In this version `makeId('a').constructor == Object`, but we could write a version where it's `null`.)  There are many in the JS community insisting that this is the only proper way to do OO in JS.  While I disagree with that extreme, it is certainly one reasonable way to do so.\r\n\r\nIt simply seems to me that if we insist that instances have the `of`, that does not preclude implementations that provide other mechanisms that seem useful, but then the laws can be simple and the implementations don't need to make these choices."}}