If you think there's a bug, you may want to file a GHC ticket about this, and include the results of your digging: https://gitlab.haskell.org/ghc/ghc/-/issues Thanks, Simon | -----Original Message----- | From: Haskell-Cafe <haskell-cafe-bounces@haskell.org> On Behalf Of | ???? | Sent: 28 April 2021 09:43 | To: Haskell Cafe <haskell-cafe@haskell.org> | Subject: Re: [Haskell-cafe] Template Haskell question | | I've been digging through GHC source code to understand the reasons | behind these behaviors. | | 1. There are use-cases of TemplateHaskell which do not want duplicate | variables in patterns to be error. See a note in source code: | | https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgitl | ab.haskell.org%2Fghc%2Fghc%2F- | %2Fblob%2Fd04a758296afdfd12300b0466967a42276a2c5a8%2Fcompiler%2FGHC%2F | ThToHs.hs%23L1981&data=04%7C01%7Csimonpj%40microsoft.com%7C2132096 | ac75c4d963e1708d90a21baef%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7 | C637551962278898308%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIj | oiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=%2FKJpA8A7Pr | d6iPc14c1Nw6DA7Ktl3axSTwTDmTd2VX4%3D&reserved=0 | | Quoting the linked note, | | > Consider this TH term construction: | > do { x1 <- TH.newName "x" -- newName :: String -> Q TH.Name | > ; x2 <- TH.newName "x" -- Builds a NameU | > ; x3 <- TH.newName "x" | > | > ; let x = mkName "x" -- mkName :: String -> TH.Name | > -- Builds a NameS | > | > ; return (LamE (..pattern [x1,x2]..) $ | > LamE (VarPat x3) $ | > ..tuple (x1,x2,x3,x)) } | > | > It represents the term \[x1,x2]. \x3. (x1,x2,x3,x) | > | > a) We don't want to complain about "x" being bound twice in | > the pattern [x1,x2] | > b) We don't want x3 to shadow the x1,x2 | > c) We *do* want 'x' (dynamically bound with mkName) to bind | > to the innermost binding of "x", namely x3. | > d) When pretty printing, we want to print a unique with x1,x2 | > etc, else they'll all print as "x" which isn't very helpful | | To do this, a variable name has one of these two flavors: | "system" flavor for names generated by `newName`, and "normal" flavor | for names made by `mkName`. Duplicate variable name error is not | checked for "system" flavored names. | | Actually, using `mkName` works in an intended way (cause error) | | ghci> (\x $(varP (mkName "x")) -> x) 1 2 | | <interactive>:10:3: error: | • Conflicting definitions for ‘x’ | Bound at: <interactive>:10:3 | <interactive>:10:7-23 | • In a lambda abstraction | | 2. Quoting brackets ([| ... |], [p| ... |]) are translated to | TemplateHaskell code (in Q Monad) by desugarar. The desugarar | represents *every* bound variable name by names generated by | TH.newName. For example, the desugared code of [| \x y -> x y y |] | looks like below: | | do { x <- newName "x"; y <- newName "y"; | return $ (LamE [VarP x, VarP y] (...) ) } | | And [p| x |] is translated in this manner too, causing the discussed | behavior. | | -- | /* Koji Miyazato <viercc@gmail.com> */ | _______________________________________________ | Haskell-Cafe mailing list | To (un)subscribe, modify options or view archives go to: | https://nam06.safelinks.protection.outlook.com/?url=http%3A%2F%2Fmail. | haskell.org%2Fcgi-bin%2Fmailman%2Flistinfo%2Fhaskell- | cafe&data=04%7C01%7Csimonpj%40microsoft.com%7C2132096ac75c4d963e17 | 08d90a21baef%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637551962278 | 908298%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJ | BTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=%2FB%2BKDrSZ%2FNG2O3lzqtB | OmPqO64raW5V0cygOLKZ%2FbxQ%3D&reserved=0 | Only members subscribed via the mailman list are allowed to post.