applicative-quoters 0.1.0.7 → 0.1.0.8
raw patch · 4 files changed
+50/−97 lines, 4 filesdep −notcppdep ~basedep ~haskell-src-metadep ~template-haskellPVP ok
version bump matches the API change (PVP)
Dependencies removed: notcpp
Dependency ranges changed: base, haskell-src-meta, template-haskell
API changes (from Hackage documentation)
Files
- ChangeLog +5/−0
- Control/Applicative/QQ/ADo.hs +30/−81
- Control/Applicative/QQ/Idiom.hs +11/−11
- applicative-quoters.cabal +4/−5
ChangeLog view
@@ -1,3 +1,8 @@+0.1.0.8:+- Doc fixes+- Since support for GHC < 7.4 was dropped, don't need notcpp or related code+- Make dependency bounds more optimistic+ 0.1.0.7: - Make it a little more obvious that the package is unmaintained
Control/Applicative/QQ/ADo.hs view
@@ -19,9 +19,6 @@ -- * Desugaring -- $desugaring-- -- * Caveats- -- $caveats ) where import Control.Applicative@@ -29,10 +26,7 @@ import Language.Haskell.TH import Language.Haskell.TH.Quote import Control.Monad-import Data.Data (cast, gmapQ) -import NotCPP.ScopeLookup (scopeLookup)- -- $desugaring -- -- If you use patterns that may fail:@@ -68,23 +62,6 @@ -- -- > foo = (\ ~(x:xs) (A y) -> T x y) <$> foo bar baz <*> quux quaffle --- $caveats------ Prior to GHC 7.4 and Template Haskell 2.7, it was impossible to reliably--- look up constructor names just from a string: if there is a type with the--- same name, it will return information for that instead.------ This means that the safe version of 'ado' is prone to failure where types--- and values share names. It tries to make a \"best guess\" in the common--- case that type and constructor have the same name, but has nontrivial--- failure modes.------ In such cases, 'ado'' should work fine: at a pinch, you--- can bind simple variables with it and case-match on them in your last--- statement.------ See also: <http://hackage.haskell.org/trac/ghc/ticket/4429>- -- | Usage: -- -- > ghci> [$ado| a <- "foo"; b <- "bar"; (a,b) |]@@ -153,72 +130,44 @@ failingPattern :: Pat -> Q Bool failingPattern pat = case pat of- LitP {} -> return True+ -- patterns that always succeed VarP {} -> return False- TupP ps -> anyFailing ps- ConP n ps -> liftM2 ((||) . not) (singleCon n) (anyFailing ps)- InfixP p n q -> failingPattern $ ConP n [p, q] TildeP {} -> return False WildP -> return False- RecP n fps -> failingPattern $ ConP n (map snd fps)+ -- patterns that can fail+ LitP {} -> return True ListP {} -> return True- -- recurse on any subpatterns- -- we do this implicitly because it avoids referring to the constructors- -- by name, which means we can work with TH versions where they didn't- -- exist- _ -> fmap or . sequence $ gmapQ (mkQ (return False) failingPattern) pat+ -- ConP can fail if the constructor is not the only constructor of its type+ -- /or/ if any of the subpatterns can fail+ ConP n ps -> liftM2 (\x y -> not x || y) (singleCon n) (anyFailing ps)+ -- some other patterns are essentially ConP patterns+ InfixP p n q -> failingPattern $ ConP n [p, q]+ UInfixP p n q -> failingPattern $ ConP n [p, q]+ RecP n fps -> failingPattern $ ConP n (map snd fps)+ -- recursive cases+ TupP ps -> anyFailing ps+ UnboxedTupP ps -> anyFailing ps+ ParensP p -> failingPattern p+ BangP p -> failingPattern p+ AsP _ p -> failingPattern p+ SigP p _ -> failingPattern p+ ViewP _ p -> failingPattern p where anyFailing = fmap or . mapM failingPattern- mkQ d f x = maybe d f (cast x) --- Uses lookupValueName when available via TH magic, otherwise tries a--- best-guess approach (see the caveats section)--- | Given a 'Name' of a value constructor, find the 'TyConI dec' of its--- type, and return 'dec'-findTyCon :: Name -> Q Dec-findTyCon n = case $(scopeLookup "lookupValueName") of- Just fn -> do- DataConI _ _ tn _ <- maybe noScope reify =<< fn (show n)- TyConI dec <- reify tn- return dec- where- noScope = fail $ "Data constructor " ++ show n ++ " not in scope"- Nothing -> do- -- This is what we do when lookupValueName isn't available.- info <- reify n- -- This covers the common case of a data type with one of the- -- constructors being named the same as the type, but fails if there- -- is a type Foo and a constructor Foo of a different type :(- TyConI dec <- case info of- DataConI _ _ tn _ -> reify tn- -- we hope that the base of the tn is the same, but it is- -- properly qualified- TyConI (DataD _ _ _ cs _)- | any rightName cs -> return info- | otherwise -> errShadow- TyConI (NewtypeD _ _ _ c _)- | rightName c -> return info- | otherwise -> errShadow- _ -> fail $ "ado singleCon: not a constructor: " ++ show info- return dec- where- rightName c = nameBase n == nameBase (conName c)- errShadow = fail . concat $ ["ado singleCon: couldn't find data ",- "dec for name: ", show n, ", sorry :( - try using ado' instead"]- -- | Take the name of a value constructor and try to find out if it is -- the only constructor of its type singleCon :: Name -> Q Bool singleCon n = do- dec <- findTyCon n- case dec of- DataD _ _ _ [_] _ -> return True- NewtypeD {} -> return True- DataD _ _ _ (_:_) _ -> return False- _ -> fail $ "ado singleCon: not a data declaration: " ++ show dec--conName :: Con -> Name-conName (NormalC n _) = n-conName (RecC n _) = n-conName (InfixC _ n _) = n-conName (ForallC _ _ c) = conName c+ dec <- recover noScope $ do+ Just vn <- lookupValueName (show n)+ DataConI _ _ tn _ <- reify vn+ TyConI dec <- reify tn+ return dec+ case dec of+ DataD _ _ _ [_] _ -> return True+ NewtypeD {} -> return True+ DataD _ _ _ (_:_) _ -> return False+ _ -> fail $ "ado singleCon: not a data declaration: " ++ show dec+ where+ noScope = fail $ "Data constructor " ++ show n ++ " lookup failed."
Control/Applicative/QQ/Idiom.hs view
@@ -11,22 +11,22 @@ import Language.Haskell.TH.Quote import Language.Haskell.TH.Syntax --- | Turns function application into <*>, and puts a pure on the beginning.+-- | Turns function application into '<*>', and puts a 'pure' on the beginning. ----- [i| subtract [1,2,3] [10,20,30] |]--- -> pure subtract <*> [1,2,3] <*> [10,20,30]--- -> [99,199,299,98,198,298,97,197,297]+-- > [i| subtract [1,2,3] [10,20,30] |]+-- > -> pure subtract <*> [1,2,3] <*> [10,20,30]+-- > -> [9,19,29,8,18,28,7,17,27] -- -- Does not apply to nested applications: ----- getZipList [i| subtract (ZipList [1,2,3]) (ZipList [100,200,300]) |]--- -> getZipList (pure subtract <*> ZipList [1,2,3] <*> ZipList [100,200,300])--- -> [99,198,297]+-- > getZipList [i| subtract (ZipList [1,2,3]) (ZipList [10,20,30]) |]+-- > -> getZipList (pure subtract <*> ZipList [1,2,3] <*> ZipList [10,20,30])+-- > -> [9,18,27] ----- Will treat [i| x `op` y |] as [i| op x y |] as long as neither x nor y--- are an infix expression. The precise behaviour when x or y are infix--- applications depends on what haskell-src-meta does, which depends on what--- TH supports, so may depend on your GHC version.+-- Will treat @[i| x \`op\` y |]@ as @[i| op x y |]@ as long as neither x nor y+-- are an infix expression. If they are, will likely complain that it doesn't+-- have fixity information (unless haskell-src-meta becomes clever enough to+-- resolve that itself). i :: QuasiQuoter i = QuasiQuoter { quoteExp = applicate <=< either fail return . parseExp, quotePat = nonsense "pattern",
applicative-quoters.cabal view
@@ -1,7 +1,7 @@ Cabal-Version: >= 1.6 Name: applicative-quoters-Version: 0.1.0.7+Version: 0.1.0.8 Category: Language Synopsis: Quasiquoters for idiom brackets and an applicative do-notation @@ -29,10 +29,9 @@ Control.Applicative.QQ.Idiom Build-depends:- base >= 4 && < 4.7,- haskell-src-meta >= 0.2 && < 0.7,- notcpp < 0.3,- template-haskell >= 2.7 && < 2.9+ base >= 4 && < 5,+ haskell-src-meta >= 0.2 && < 1,+ template-haskell >= 2.7 && < 3 Extensions: TemplateHaskell