{"action":"closed","issue":{"url":"https://api.github.com/repos/purescript/purescript-quickcheck/issues/49","labels_url":"https://api.github.com/repos/purescript/purescript-quickcheck/issues/49/labels{/name}","comments_url":"https://api.github.com/repos/purescript/purescript-quickcheck/issues/49/comments","events_url":"https://api.github.com/repos/purescript/purescript-quickcheck/issues/49/events","html_url":"https://github.com/purescript/purescript-quickcheck/issues/49","id":124666733,"number":49,"title":"Advice on using newtype wrappers to avoid orphan instances of Arbitrary","user":{"login":"paulyoung","id":84700,"avatar_url":"https://avatars.githubusercontent.com/u/84700?v=3","gravatar_id":"","url":"https://api.github.com/users/paulyoung","html_url":"https://github.com/paulyoung","followers_url":"https://api.github.com/users/paulyoung/followers","following_url":"https://api.github.com/users/paulyoung/following{/other_user}","gists_url":"https://api.github.com/users/paulyoung/gists{/gist_id}","starred_url":"https://api.github.com/users/paulyoung/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/paulyoung/subscriptions","organizations_url":"https://api.github.com/users/paulyoung/orgs","repos_url":"https://api.github.com/users/paulyoung/repos","events_url":"https://api.github.com/users/paulyoung/events{/privacy}","received_events_url":"https://api.github.com/users/paulyoung/received_events","type":"User","site_admin":false},"labels":[],"state":"closed","locked":false,"assignee":null,"milestone":null,"comments":3,"created_at":"2016-01-03T19:28:13Z","updated_at":"2016-01-26T08:15:02Z","closed_at":"2016-01-26T08:15:02Z","body":"Given the following module, I'm struggling to be able to create a test module that has arbitrary instances of `Position`.\r\n\r\nI think the problem stems from either not understanding how to properly use `newtype` wrappers to avoid orphan instances of `Arbitrary`, or that doing so isn't sufficient since other type class instances aren't implemented for the wrapper.\r\n\r\nFor `Position`, I've tried using:\r\n\r\n```purescript\r\nnewtype TestPosition = TestPosition Position\r\n```\r\n\r\nand:\r\n\r\n```purescript\r\nnewtype TestPosition = TestPosition\r\n  { line :: Int\r\n  , column :: Int\r\n  }\r\n```\r\n\r\nbut ultimately keep ending up with the following error:\r\n\r\n```\r\n  Could not match type\r\n\r\n    TestPosition\r\n\r\n  with type\r\n\r\n    Position\r\n```\r\n\r\nHopefully I'm missing something rather simple, and would appreciate some guidance.\r\n\r\nA minimal example can be found below. Thanks in advance.\r\n\r\n***\r\n\r\n```purescript\r\nmodule ESTree where\r\n\r\nimport Prelude (Eq, Ord, Show)\r\n\r\nimport Data.Foreign.Class (IsForeign)\r\nimport Data.Foreign.Generic (Options(), defaultOptions, readGeneric)\r\nimport Data.Generic (Generic, gCompare, gEq, gShow)\r\nimport Data.Maybe (Maybe())\r\n\r\n\r\noptions :: Options\r\noptions = defaultOptions { unwrapNewtypes = true }\r\n\r\n\r\nnewtype SourceLocation = SourceLocation\r\n  { source :: Maybe String\r\n  , start :: Position\r\n  , end :: Position\r\n  }\r\n\r\nderive instance genericSourceLocation :: Generic SourceLocation\r\n\r\ninstance isForeignSourceLocation :: IsForeign SourceLocation where\r\n  read = readGeneric options\r\n\r\ninstance showSourceLocation :: Show SourceLocation where\r\n  show = gShow\r\n\r\ninstance eqSourceLocation :: Eq SourceLocation where\r\n  eq = gEq\r\n\r\ninstance ordSourceLocation :: Ord SourceLocation where\r\n  compare = gCompare\r\n\r\n\r\nnewtype Position = Position\r\n  { line :: Int\r\n  , column :: Int\r\n  }\r\n\r\nderive instance genericPosition :: Generic Position\r\n\r\ninstance isForeignPosition :: IsForeign Position where\r\n  read = readGeneric options\r\n\r\ninstance showPosition :: Show Position where\r\n  show = gShow\r\n\r\ninstance eqPosition :: Eq Position where\r\n  eq = gEq\r\n\r\ninstance ordPosition :: Ord Position where\r\n  compare = gCompare\r\n```\r\n\r\n```purescript\r\nmodule Test.Main where\r\n\r\nimport Prelude (Show, Unit(), ($), (==), (++), bind, return, show)\r\nimport Control.Monad.Eff.Console (log)\r\n\r\nimport Test.QuickCheck (QC(), Result(), (<?>), quickCheck)\r\nimport Test.QuickCheck.Arbitrary (Arbitrary, arbitrary)\r\n\r\nimport Data.Either (Either(Right))\r\nimport Data.Foreign.Class (readJSON)\r\nimport Data.Maybe (Maybe())\r\n\r\nimport ESTree\r\n  ( Position(..)\r\n  , SourceLocation(..)\r\n  )\r\n\r\n\r\nlogError :: forall a b. (Show a) => (Show b) => a -> b -> String\r\nlogError actual expected = \"\"\r\n  ++ \"\\n\"\r\n  ++ \"Actual:\" ++ \"\\n\"\r\n  ++ \"  \" ++ show actual ++ \"\\n\"\r\n  ++ \"\\n\"\r\n  ++ \"Expected:\" ++ \"\\n\"\r\n  ++ \"  \" ++ show expected ++ \"\\n\"\r\n\r\n\r\nnewtype TestPosition = TestPosition\r\n  { line :: Int\r\n  , column :: Int\r\n  }\r\n\r\ninstance arbTestPosition :: Arbitrary TestPosition where\r\n  arbitrary = do\r\n    line <- arbitrary\r\n    column <- arbitrary\r\n    return $ TestPosition { line: line\r\n                          , column: column\r\n                          }\r\n\r\n\r\nmain :: QC () Unit\r\nmain = do\r\n\r\n  log \"Checking Position\"\r\n  quickCheck checkPosition\r\n\r\n  log \"Checking SourceLocation\"\r\n  quickCheck checkSourceLocation\r\n\r\n  where\r\n\r\n  checkPosition :: Int -> Int -> Result\r\n  checkPosition line column = do\r\n    let json = \"{ \\\"line\\\": \" ++ show line ++\r\n               \", \\\"column\\\": \" ++ show column ++\r\n               \"}\"\r\n\r\n    let expected = Right $ Position { line: line\r\n                                    , column: column\r\n                                    }\r\n    let actual = readJSON json\r\n\r\n    actual == expected <?> logError actual expected\r\n\r\n\r\n  checkSourceLocation :: (Maybe String) -> TestPosition -> TestPosition -> Result\r\n  checkSourceLocation source start end = do\r\n    let json = \"{ \\\"source\\\": \" ++ show source ++\r\n               \", \\\"start\\\": \" ++ show start ++\r\n               \", \\\"end\\\": \" ++ show end ++\r\n               \"}\"\r\n\r\n    let expected = Right $ SourceLocation { source: source\r\n                                          , start: start\r\n                                          , end: end\r\n                                          }\r\n    let actual = readJSON json\r\n\r\n    actual == expected <?> logError actual expected\r\n```"}}