{"action":"created","issue":{"url":"https://api.github.com/repos/ocharles/exhaustive/issues/2","labels_url":"https://api.github.com/repos/ocharles/exhaustive/issues/2/labels{/name}","comments_url":"https://api.github.com/repos/ocharles/exhaustive/issues/2/comments","events_url":"https://api.github.com/repos/ocharles/exhaustive/issues/2/events","html_url":"https://github.com/ocharles/exhaustive/issues/2","id":53952829,"number":2,"title":"The approach is error-prone","user":{"login":"feuerbach","id":24844,"avatar_url":"https://avatars.githubusercontent.com/u/24844?v=3","gravatar_id":"","url":"https://api.github.com/users/feuerbach","html_url":"https://github.com/feuerbach","followers_url":"https://api.github.com/users/feuerbach/followers","following_url":"https://api.github.com/users/feuerbach/following{/other_user}","gists_url":"https://api.github.com/users/feuerbach/gists{/gist_id}","starred_url":"https://api.github.com/users/feuerbach/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/feuerbach/subscriptions","organizations_url":"https://api.github.com/users/feuerbach/orgs","repos_url":"https://api.github.com/users/feuerbach/repos","events_url":"https://api.github.com/users/feuerbach/events{/privacy}","received_events_url":"https://api.github.com/users/feuerbach/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":14,"created_at":"2015-01-10T09:43:04Z","updated_at":"2015-01-11T13:55:34Z","closed_at":null,"body":"I agree with the premise of this library: let's make errors harder to commit.\r\n\r\nUnfortunately, this specific approach makes it even easier to commit certain types of errors. In your example, if I swap `ETrue` and `EFalse` around, not only will the compiler not catch it, but it also becomes harder to spot the error when reading the code than it would be in the original, naive code:\r\n\r\n```\r\n  ETrue <$ symbol \"False\"\r\n, EFalse <$ symbol \"True\"\r\n```\r\n\r\nvs\r\n\r\n```\r\n  construct (\\f -> f <$ symbol \"False\") :*\r\n  construct (\\f -> f <$ symbol \"True\") :*\r\n```"},"comment":{"url":"https://api.github.com/repos/ocharles/exhaustive/issues/comments/69495225","html_url":"https://github.com/ocharles/exhaustive/issues/2#issuecomment-69495225","issue_url":"https://api.github.com/repos/ocharles/exhaustive/issues/2","id":69495225,"user":{"login":"ocharles","id":20878,"avatar_url":"https://avatars.githubusercontent.com/u/20878?v=3","gravatar_id":"","url":"https://api.github.com/users/ocharles","html_url":"https://github.com/ocharles","followers_url":"https://api.github.com/users/ocharles/followers","following_url":"https://api.github.com/users/ocharles/following{/other_user}","gists_url":"https://api.github.com/users/ocharles/gists{/gist_id}","starred_url":"https://api.github.com/users/ocharles/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ocharles/subscriptions","organizations_url":"https://api.github.com/users/ocharles/orgs","repos_url":"https://api.github.com/users/ocharles/repos","events_url":"https://api.github.com/users/ocharles/events{/privacy}","received_events_url":"https://api.github.com/users/ocharles/received_events","type":"User","site_admin":false},"created_at":"2015-01-11T13:55:34Z","updated_at":"2015-01-11T13:55:34Z","body":"I had a play with this, and I think I'm barking up the wrong tree with quasiquoters - but splicing in a peano number with Template Haskell is looking somewhat promising. Here's what I have:\r\n\r\n```haskell\r\nparseExpr :: Parser Expr\r\nparseExpr =\r\n  produceFirst $\r\n  cons $(con 'ETrue) (construct (\\f -> f <$ symbol \"True\")) $\r\n  cons $(con 'EFalse) (construct (\\f -> f <$ symbol \"False\")) $\r\n  cons $(con 'EIf) (construct (\\f -> f <$> (symbol \"if\" *> parseExpr)\r\n                                      <*> (symbol \"then\" *> parseExpr)\r\n                                      <*> (symbol \"else\" *> parseExpr))) $\r\n  Nil\r\n```\r\n\r\nThis type checks that you use all constructors in the same order as the original data definition. We have...\r\n\r\n```haskell\r\ncons :: (Length code ~ (n + Length xs)) => Proxy n -> Producer f code x -> NP (Producer f code) xs -> NP (Producer f code) (x ': xs)\r\n```\r\n\r\nThis means forces a total ordering on `cons`.\r\n"}}