{"action":"created","issue":{"url":"https://api.github.com/repos/purescript/purescript/issues/868","labels_url":"https://api.github.com/repos/purescript/purescript/issues/868/labels{/name}","comments_url":"https://api.github.com/repos/purescript/purescript/issues/868/comments","events_url":"https://api.github.com/repos/purescript/purescript/issues/868/events","html_url":"https://github.com/purescript/purescript/issues/868","id":57499229,"number":868,"title":"Revise Num class","user":{"login":"paf31","id":630306,"avatar_url":"https://avatars.githubusercontent.com/u/630306?v=3","gravatar_id":"","url":"https://api.github.com/users/paf31","html_url":"https://github.com/paf31","followers_url":"https://api.github.com/users/paf31/followers","following_url":"https://api.github.com/users/paf31/following{/other_user}","gists_url":"https://api.github.com/users/paf31/gists{/gist_id}","starred_url":"https://api.github.com/users/paf31/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/paf31/subscriptions","organizations_url":"https://api.github.com/users/paf31/orgs","repos_url":"https://api.github.com/users/paf31/repos","events_url":"https://api.github.com/users/paf31/events{/privacy}","received_events_url":"https://api.github.com/users/paf31/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/purescript/purescript/labels/enhancement","name":"enhancement","color":"84b6eb"},{"url":"https://api.github.com/repos/purescript/purescript/labels/libraries","name":"libraries","color":"0052cc"}],"state":"open","locked":false,"assignee":{"login":"garyb","id":693642,"avatar_url":"https://avatars.githubusercontent.com/u/693642?v=3","gravatar_id":"","url":"https://api.github.com/users/garyb","html_url":"https://github.com/garyb","followers_url":"https://api.github.com/users/garyb/followers","following_url":"https://api.github.com/users/garyb/following{/other_user}","gists_url":"https://api.github.com/users/garyb/gists{/gist_id}","starred_url":"https://api.github.com/users/garyb/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/garyb/subscriptions","organizations_url":"https://api.github.com/users/garyb/orgs","repos_url":"https://api.github.com/users/garyb/repos","events_url":"https://api.github.com/users/garyb/events{/privacy}","received_events_url":"https://api.github.com/users/garyb/received_events","type":"User","site_admin":false},"milestone":{"url":"https://api.github.com/repos/purescript/purescript/milestones/9","labels_url":"https://api.github.com/repos/purescript/purescript/milestones/9/labels","id":857545,"number":9,"title":"0.7.0","description":"","creator":{"login":"paf31","id":630306,"avatar_url":"https://avatars.githubusercontent.com/u/630306?v=3","gravatar_id":"","url":"https://api.github.com/users/paf31","html_url":"https://github.com/paf31","followers_url":"https://api.github.com/users/paf31/followers","following_url":"https://api.github.com/users/paf31/following{/other_user}","gists_url":"https://api.github.com/users/paf31/gists{/gist_id}","starred_url":"https://api.github.com/users/paf31/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/paf31/subscriptions","organizations_url":"https://api.github.com/users/paf31/orgs","repos_url":"https://api.github.com/users/paf31/repos","events_url":"https://api.github.com/users/paf31/events{/privacy}","received_events_url":"https://api.github.com/users/paf31/received_events","type":"User","site_admin":false},"open_issues":24,"closed_issues":53,"state":"open","created_at":"2014-11-07T16:03:12Z","updated_at":"2015-02-15T00:26:46Z","due_on":null,"closed_at":null},"comments":59,"created_at":"2015-02-12T18:26:17Z","updated_at":"2015-02-15T23:30:01Z","closed_at":null,"body":"This could become a huge discussion, but I'll say up front - I don't want to do anything drastic to `Num` all at once.\r\n\r\nA very refined type class hierarchy _is_ possible, but I think would be better contained in libraries.\r\n\r\nThat said, I'm pretty sure `Number` is the only instance of `Num` right now (no `Int` yet, etc.) and I don't think any code uses `Num` in the abstract, so we can change a few things, if we're careful not to break the optimizer.\r\n\r\nHere is the current proposal (by @jdegoes):\r\n\r\n```purescript\r\n-- addition and multiplication\r\nclass Semiring a where \r\n  (+)   :: a -> a -> a\r\n  zero  :: a\r\n  (*)   :: a -> a -> a\r\n  one   :: a\r\n\r\n-- addition, multiplication, and subtraction\r\nclass (Semiring a) <= Ring a where\r\n  (-) :: a -> a -> a\r\n\r\nnegate :: forall a. (Ring a) => a -> a\r\nnegate a = zero - a\r\n\r\n-- ring with division (possibly non-commutative field)\r\nclass (Ring a) <= DivisionRing a where\r\n  (/) :: a -> a -> a\r\n\r\n-- definitely commutative field\r\nclass (DivisionRing a) <= Num a\r\n```\r\n\r\nand in `purescript-monoids`:\r\n\r\n```purescript\r\n-- additive monoid\r\nnewtype Additive a = Additive a\r\n\r\n-- multiplicative monoid\r\nnewtype Multiplicative a = Multiplicative a\r\n\r\ninstance additiveSemiRing :: (SemiRing a) => Semigroup (Additive a) where \r\n  (<>) (Additive a) (Additive b) = Additive (a + b)\r\n\r\ninstance additiveMonoid :: (SemiRing a) => Monoid (Additive a) where\r\n  mempty = Additive zero\r\n\r\n-- todo: Additive functor, applicative, etc.\r\n\r\ninstance multiplicativeSemiRing :: (SemiRing a) => Semigroup (Multiplicative a) where \r\n  (<>) (Multiplicative a) (Multiplicative b) = Multiplicative (a + b)\r\n\r\ninstance multiplicativeMonoid :: (SemiRing a) => Monoid (Multiplicative a) where\r\n  mempty = Multiplicative one\r\n\r\n-- todo: Multiplicative functor, applicative, etc. \r\n```"},"comment":{"url":"https://api.github.com/repos/purescript/purescript/issues/comments/74443648","html_url":"https://github.com/purescript/purescript/issues/868#issuecomment-74443648","issue_url":"https://api.github.com/repos/purescript/purescript/issues/868","id":74443648,"user":{"login":"paf31","id":630306,"avatar_url":"https://avatars.githubusercontent.com/u/630306?v=3","gravatar_id":"","url":"https://api.github.com/users/paf31","html_url":"https://github.com/paf31","followers_url":"https://api.github.com/users/paf31/followers","following_url":"https://api.github.com/users/paf31/following{/other_user}","gists_url":"https://api.github.com/users/paf31/gists{/gist_id}","starred_url":"https://api.github.com/users/paf31/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/paf31/subscriptions","organizations_url":"https://api.github.com/users/paf31/orgs","repos_url":"https://api.github.com/users/paf31/repos","events_url":"https://api.github.com/users/paf31/events{/privacy}","received_events_url":"https://api.github.com/users/paf31/received_events","type":"User","site_admin":false},"created_at":"2015-02-15T23:30:01Z","updated_at":"2015-02-15T23:30:01Z","body":"Yes, for a field, every non-zero element has a multiplicative inverse, so\r\n\r\n```\r\na / b * b + (a % b) = a\r\n{ a / b = a * inv(b) }\r\n==> a * inv (b) * b + a % b = a\r\n{ inv (b) * b = 1 }\r\n==> a + a % b = a\r\n{ subtract a }\r\n==> a % b = 0\r\n```"}}