packages feed

constraint-tuples 0.1 → 0.1.1

raw patch · 7 files changed

+277/−209 lines, 7 filesdep −base-compat-batteriesdep −optparse-applicativePVP ok

version bump matches the API change (PVP)

Dependencies removed: base-compat-batteries, optparse-applicative

API changes (from Hackage documentation)

Files

CHANGELOG.md view
@@ -1,2 +1,7 @@+### 0.1.1 [2019.10.21]+* Split `generator-script` out of the main `.cabal` file, as it is only used+  for development purposes.+* Minor Haddock fixes.+ ## 0.1 [2019.10.14] * First version.
constraint-tuples.cabal view
@@ -1,6 +1,6 @@ cabal-version:       >=1.10 name:                constraint-tuples-version:             0.1+version:             0.1.1 synopsis:            Partially applicable constraint tuples description:         This library provides classes that emulate the behavior of                      GHC's constraint tuple syntax. Unlike GHC's built-in@@ -27,7 +27,12 @@ copyright:           (C) 2018-2019 Ryan Scott category:            Data build-type:          Simple-extra-source-files:  CHANGELOG.md, README.md, GenCTuples.sh+extra-source-files:  CHANGELOG.md+                     README.md+                     GenCTuples.sh+                     generator-script/LICENSE+                     generator-script/generator-script.cabal+                     generator-script/exe/GeneratorScript.hs tested-with:         GHC == 7.6.3                    , GHC == 7.8.4                    , GHC == 7.10.3@@ -41,11 +46,6 @@   type:                git   location:            https://github.com/RyanGlScott/constraint-tuples -flag generator-script-  description:         Build the script which generates the source code for-                       this library.-  default:             False- library   exposed-modules:     Data.Tuple.Constraint                        Data.Tuple.Constraint.ClassNewtype@@ -53,15 +53,3 @@   hs-source-dirs:      src   default-language:    Haskell2010   ghc-options:         -Wall--executable generator-script-  if !flag(generator-script)-    buildable:         False--  main-is:             GeneratorScript.hs-  build-depends:       base                  >= 4.6  && < 5-                     , base-compat-batteries >= 0.10 && < 0.12-                     , optparse-applicative  >= 0.13 && < 0.16-  hs-source-dirs:      exe-  default-language:    Haskell2010-  ghc-options:         -Wall -threaded -rtsopts
− exe/GeneratorScript.hs
@@ -1,189 +0,0 @@-{-# LANGUAGE NamedFieldPuns #-}--- | The script that generates the source code for "Data.Tuple.Constraint" and--- "Data.Tuple.Constraint.ClassNewtype". See the @GenCTuple.sh@ script for how--- to invoke this.-module Main (main) where--import Data.List.Compat-import Prelude ()-import Prelude.Compat-import Options.Applicative--data Args = Args-  { output       :: FilePath-  , classNewtype :: Bool-  } deriving Show--argsParser :: Parser Args-argsParser = Args-  <$> strOption-      (  long "output"-      <> short 'o'-      <> metavar "PATH"-      <> help "The file to which to write the source code" )-  <*> switch-      (  long "class-newtype"-      <> help "Generate the source code for Data.Tuple.Constraint.ClassNewtype" )--main :: IO ()-main = execParser opts >>= generate-  where-    opts = info (argsParser <**> helper)-      ( fullDesc-     <> progDesc spiel-     <> header spiel )--    spiel = "Generate the source code for Data.Tuple.Constraint{,.ClassNewtype}"--generate :: Args -> IO ()-generate args@Args{output} =-  let sourceCode = unlines $ preamble args ++ decs args in-  writeFile output sourceCode--genCTuple :: Args -> Word -> String-genCTuple Args{classNewtype} n-  | n == 0    = "CTuple0"-  | otherwise = parens (concat (intersperse ", " cNums))-             ++ " => CTuple" ++ show n ++ " " ++ unwords cNums-  where-    parens :: String -> String-    parens s | n == 1    = s-             | otherwise = kindSig $ "(" ++ s ++ ")"--    kindSig :: String -> String-    kindSig s | classNewtype = "(" ++ s ++ " :: Constraint)"-              | otherwise    = s--    cNums :: [String]-    cNums = ['c':show i | i <- [1..n]]--haddocks :: Word -> [String]-haddocks i =-  [ "-- | A constraint tuple class with " ++ show i ++ " arguments."-  ] ++-  if i == 0-  then [ "--"-       , "-- This class is only defined on GHC 7.8 or later."-       ]-  else []--maxTupleSize :: Word-maxTupleSize = 62--preamble :: Args -> [String]-preamble Args{classNewtype} =-  [ "{-# LANGUAGE ConstraintKinds #-}"-  , "{-# LANGUAGE CPP #-}"-  , "{-# LANGUAGE FlexibleInstances #-}"-  , "{-# LANGUAGE KindSignatures #-}"-  , "{-# LANGUAGE MultiParamTypeClasses #-}"-  , "{-# LANGUAGE UndecidableInstances #-}"-  , "#if __GLASGOW_HASKELL__ >= 708 && __GLASGOW_HASKELL__ < 710"-  , "{-# LANGUAGE NullaryTypeClasses #-}"-  , "#endif"-  , "#if __GLASGOW_HASKELL__ >= 800"-  , "{-# LANGUAGE UndecidableSuperClasses #-}"-  , "#endif"-  ] ++ safeHaskell ++-  [ "-- | This module provides classes that emulate the behavior of GHC's constraint"-  , "-- tuple syntax. Unlike GHC's built-in constraint tuples, the classes in this"-  , "-- library can be partially applied."-  , "--"-  ] ++ haddockNote ++-  [ "module " ++ modName-  , "  ( -- * Constraint tuples"-  ] ++ exports ++-  [ "  ) where"-  , ""-  ] ++ imports-  where-    modName :: String-    modName = "Data.Tuple.Constraint" ++-              if classNewtype then ".ClassNewtype" else ""--    exports :: [String]-    exports = flip concatMap [0..maxTupleSize] $ \i ->-                case i of-                  0 -> [ "#if __GLASGOW_HASKELL__ >= 708"-                       , "    CTuple0,"-                       , "#endif"-                       ]-                  1 -> [ "    CTuple1" ]-                  _ -> [ "  , CTuple" ++ show i ]--    imports :: [String]-    imports | classNewtype-            = [ "import Data.Tuple.Constraint ( CTuple1"-              , "#if __GLASGOW_HASKELL__ >= 708"-              , "                             , CTuple0"-              , "#endif"-              , "                             )"-              , "#if __GLASGOW_HASKELL__ >= 800"-              , "import Data.Kind (Constraint)"-              , "#else"-              , "import GHC.Exts (Constraint)"-              , "#endif"-              , ""-              ]-            | otherwise-            = []--    safeHaskell :: [String]-    safeHaskell | classNewtype-                = [ "#if __GLASGOW_HASKELL__ >= 800"-                  , "{-# LANGUAGE Safe #-}"-                  , "#else"-                  , "{-# LANGUAGE Trustworthy #-}"-                  , "#endif"-                  ]-                | otherwise-                = [ "{-# LANGUAGE Safe #-}" ]--    haddockNote :: [String]-    haddockNote-      | classNewtype-      = [ "-- Unlike \"Data.Tuple.Constraint\", a @CTupleN@ class defined in this module"-        , "-- (where @N@ is greater than 1) compiles to a newtype around the corresponding"-        , "-- built-in constraint tuple type with @N@ arguments in Core. In contrast, a"-        , "-- @CTupleN@ class defined in \"Data.Tuple.Constraint\" compiles to a"-        , "-- dictionary data type with @N@ fields in Core."-        , "--"-        , "-- For most use cases, this distinction is of no practical consequence. One"-        , "-- scenario where you may benefit from using this module is when you are"-        , "-- interoperating with built-in constraint tuple syntax."-        , "-- For example, in this code:"-        , "--"-        , "-- @"-        , "-- data Dict :: Constraint -> Type where"-        , "--   Dict :: c => Dict c"-        , "--"-        , "-- foo :: CTuple2 a b => Dict (a, b)"-        , "-- foo = Dict"-        , "-- @"-        , "--"-        , "-- If you use the @CTuple2@ class from \"Data.Tuple.Constraint\" to define"-        , "-- @foo@, then in the Core for @foo@, the @a@ and @b@ must be extracted from"-        , "-- the @CTuple2@ dictionary before building the @Dict@ dictionary. On the other"-        , "-- hand, if you use the @CTuple@ class from this module, then no such"-        , "-- extraction is necessary, as the Core can simply cast the @CTuple2@"-        , "-- dictionary (which is a newtype) to the @(a, b)@ dictionary and use that to"-        , "-- construct a @Dict@ dictionary."-        ]-      | otherwise-      = []--decs :: Args -> [String]-decs args@Args{classNewtype} =-  flip concatMap [0..maxTupleSize] $ \i ->-    let cTuple = genCTuple args i in-    if classNewtype && (i == 0 || i == 1)-       then [] -- CTuple{0,1} are imported from Data.Tuple.Constraint-       else concat-              [ [ "#if __GLASGOW_HASKELL__ >= 708" | i == 0 ]-              , haddocks i-              , [ "class    " ++ cTuple-                , "instance " ++ cTuple-                ]-              , [ "#endif" | i == 0 ]-              , [ "" ]-              ]
+ generator-script/LICENSE view
@@ -0,0 +1,30 @@+Copyright (c) 2018-2019, Ryan Scott++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++    * Redistributions of source code must retain the above copyright+      notice, this list of conditions and the following disclaimer.++    * Redistributions in binary form must reproduce the above+      copyright notice, this list of conditions and the following+      disclaimer in the documentation and/or other materials provided+      with the distribution.++    * Neither the name of Ryan Scott nor the names of other+      contributors may be used to endorse or promote products derived+      from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ generator-script/exe/GeneratorScript.hs view
@@ -0,0 +1,194 @@+{-# LANGUAGE NamedFieldPuns #-}+-- | The script that generates the source code for "Data.Tuple.Constraint" and+-- "Data.Tuple.Constraint.ClassNewtype". See the @GenCTuple.sh@ script for how+-- to invoke this.+module Main (main) where++import Data.List.Compat+import GHC.Exts (maxTupleSize)+import Prelude ()+import Prelude.Compat+import Options.Applicative++data Args = Args+  { output       :: FilePath+  , classNewtype :: Bool+  } deriving Show++argsParser :: Parser Args+argsParser = Args+  <$> strOption+      (  long "output"+      <> short 'o'+      <> metavar "PATH"+      <> help "The file to which to write the source code" )+  <*> switch+      (  long "class-newtype"+      <> help "Generate the source code for Data.Tuple.Constraint.ClassNewtype" )++main :: IO ()+main = execParser opts >>= generate+  where+    opts = info (argsParser <**> helper)+      ( fullDesc+     <> progDesc spiel+     <> header spiel )++    spiel = "Generate the source code for Data.Tuple.Constraint{,.ClassNewtype}"++generate :: Args -> IO ()+generate args@Args{output} =+  let sourceCode = unlines $ preamble args ++ decs args in+  writeFile output sourceCode++genCTuple :: Args -> Int -> String+genCTuple Args{classNewtype} n+  | n == 0    = "CTuple0"+  | otherwise = parens (concat (intersperse ", " cNums))+             ++ " => CTuple" ++ show n ++ " " ++ unwords cNums+  where+    parens :: String -> String+    parens s | n == 1    = s+             | otherwise = kindSig $ "(" ++ s ++ ")"++    kindSig :: String -> String+    kindSig s | classNewtype = "(" ++ s ++ " :: Constraint)"+              | otherwise    = s++    cNums :: [String]+    cNums = ['c':show i | i <- [1..n]]++haddocks :: Int -> [String]+haddocks i =+  [ "-- | A constraint tuple class with " ++ show i +++    " argument" ++ pluralSuffix ++ "."+  ] +++  if i == 0+  then [ "--"+       , "-- This class is only defined on GHC 7.8 or later."+       ]+  else []+  where+    pluralSuffix :: String+    pluralSuffix | i == 1+                 = ""+                 | otherwise+                 = "s"++preamble :: Args -> [String]+preamble Args{classNewtype} =+  [ "{-# LANGUAGE ConstraintKinds #-}"+  , "{-# LANGUAGE CPP #-}"+  , "{-# LANGUAGE FlexibleInstances #-}"+  , "{-# LANGUAGE KindSignatures #-}"+  , "{-# LANGUAGE MultiParamTypeClasses #-}"+  , "{-# LANGUAGE UndecidableInstances #-}"+  , "#if __GLASGOW_HASKELL__ >= 708 && __GLASGOW_HASKELL__ < 710"+  , "{-# LANGUAGE NullaryTypeClasses #-}"+  , "#endif"+  , "#if __GLASGOW_HASKELL__ >= 800"+  , "{-# LANGUAGE UndecidableSuperClasses #-}"+  , "#endif"+  ] ++ safeHaskell +++  [ "-- | This module provides classes that emulate the behavior of GHC's constraint"+  , "-- tuple syntax. Unlike GHC's built-in constraint tuples, the classes in this"+  , "-- library can be partially applied."+  , "--"+  ] ++ haddockNote +++  [ "module " ++ modName+  , "  ( -- * Constraint tuples"+  ] ++ exports +++  [ "  ) where"+  , ""+  ] ++ imports+  where+    modName :: String+    modName = "Data.Tuple.Constraint" +++              if classNewtype then ".ClassNewtype" else ""++    exports :: [String]+    exports = flip concatMap [0..maxTupleSize] $ \i ->+                case i of+                  0 -> [ "#if __GLASGOW_HASKELL__ >= 708"+                       , "    CTuple0,"+                       , "#endif"+                       ]+                  1 -> [ "    CTuple1" ]+                  _ -> [ "  , CTuple" ++ show i ]++    imports :: [String]+    imports | classNewtype+            = [ "import Data.Tuple.Constraint ( CTuple1"+              , "#if __GLASGOW_HASKELL__ >= 708"+              , "                             , CTuple0"+              , "#endif"+              , "                             )"+              , "#if __GLASGOW_HASKELL__ >= 800"+              , "import Data.Kind (Constraint)"+              , "#else"+              , "import GHC.Exts (Constraint)"+              , "#endif"+              , ""+              ]+            | otherwise+            = []++    safeHaskell :: [String]+    safeHaskell | classNewtype+                = [ "#if __GLASGOW_HASKELL__ >= 800"+                  , "{-# LANGUAGE Safe #-}"+                  , "#else"+                  , "{-# LANGUAGE Trustworthy #-}"+                  , "#endif"+                  ]+                | otherwise+                = [ "{-# LANGUAGE Safe #-}" ]++    haddockNote :: [String]+    haddockNote+      | classNewtype+      = [ "-- Unlike \"Data.Tuple.Constraint\", a @CTupleN@ class defined in this module"+        , "-- (where @N@ is greater than 1) compiles to a newtype around the corresponding"+        , "-- built-in constraint tuple type with @N@ arguments in Core. In contrast, a"+        , "-- @CTupleN@ class defined in \"Data.Tuple.Constraint\" compiles to a"+        , "-- dictionary data type with @N@ fields in Core."+        , "--"+        , "-- For most use cases, this distinction is of no practical consequence. One"+        , "-- scenario where you may benefit from using this module is when you are"+        , "-- interoperating with built-in constraint tuple syntax."+        , "-- For example, in this code:"+        , "--"+        , "-- @"+        , "-- data Dict :: Constraint -> Type where"+        , "--   Dict :: c => Dict c"+        , "--"+        , "-- foo :: CTuple2 a b => Dict (a, b)"+        , "-- foo = Dict"+        , "-- @"+        , "--"+        , "-- If you use the @CTuple2@ class from \"Data.Tuple.Constraint\" to define"+        , "-- @foo@, then in the Core for @foo@, the @a@ and @b@ must be extracted from"+        , "-- the @CTuple2@ dictionary before building the @Dict@ dictionary. On the other"+        , "-- hand, if you use the @CTuple@ class from this module, then no such"+        , "-- extraction is necessary, as the Core can simply cast the @CTuple2@"+        , "-- dictionary (which is a newtype) to the @(a, b)@ dictionary and use that to"+        , "-- construct a @Dict@ dictionary."+        ]+      | otherwise+      = []++decs :: Args -> [String]+decs args@Args{classNewtype} =+  flip concatMap [0..maxTupleSize] $ \i ->+    let cTuple = genCTuple args i in+    if classNewtype && (i == 0 || i == 1)+       then [] -- CTuple{0,1} are imported from Data.Tuple.Constraint+       else concat+              [ [ "#if __GLASGOW_HASKELL__ >= 708" | i == 0 ]+              , haddocks i+              , [ "class    " ++ cTuple+                , "instance " ++ cTuple+                ]+              , [ "#endif" | i == 0 ]+              , [ "" ]+              ]
+ generator-script/generator-script.cabal view
@@ -0,0 +1,40 @@+cabal-version:       >=1.10+name:                generator-script+version:             0.1+synopsis:            Generate constraint-tuples' source code+description:         The script that generates the source code for+                     "Data.Tuple.Constraint" and+                     "Data.Tuple.Constraint.ClassNewtype". See the+                     @GenCTuple.sh@ script for how to invoke this.+homepage:            https://github.com/RyanGlScott/constraint-tuples+bug-reports:         https://github.com/RyanGlScott/constraint-tuples/issues+license:             BSD3+license-file:        LICENSE+author:              Ryan Scott+maintainer:          ryan.gl.scott@gmail.com+stability:           Stable+copyright:           (C) 2018-2019 Ryan Scott+category:            Data+build-type:          Simple+tested-with:         GHC == 7.6.3+                   , GHC == 7.8.4+                   , GHC == 7.10.3+                   , GHC == 8.0.2+                   , GHC == 8.2.2+                   , GHC == 8.4.4+                   , GHC == 8.6.5+                   , GHC == 8.8.1++source-repository head+  type:                git+  location:            https://github.com/RyanGlScott/constraint-tuples+  subdir:              generator-script++executable generator-script+  main-is:             GeneratorScript.hs+  build-depends:       base                  >= 4.6  && < 5+                     , base-compat-batteries >= 0.10 && < 0.12+                     , optparse-applicative  >= 0.13 && < 0.16+  hs-source-dirs:      exe+  default-language:    Haskell2010+  ghc-options:         -Wall -threaded -rtsopts
src/Data/Tuple/Constraint.hs view
@@ -92,7 +92,7 @@ instance CTuple0 #endif --- | A constraint tuple class with 1 arguments.+-- | A constraint tuple class with 1 argument. class    c1 => CTuple1 c1 instance c1 => CTuple1 c1