digit 0.1.2 → 0.15
raw patch · 47 files changed
Files
- CONTRIBUTORS +33/−0
- LICENCE +33/−0
- Setup.hs +2/−0
- Setup.lhs +0/−44
- changelog.md +117/−0
- digit.cabal +71/−37
- etc/CONTRIBUTORS +0/−33
- etc/LICENCE +0/−27
- src/Data/Digit.hs +25/−14
- src/Data/Digit/Binary.hs +57/−0
- src/Data/Digit/Char.hs +239/−0
- src/Data/Digit/Class/D0.hs +50/−0
- src/Data/Digit/Class/D1.hs +49/−0
- src/Data/Digit/Class/D2.hs +49/−0
- src/Data/Digit/Class/D3.hs +49/−0
- src/Data/Digit/Class/D4.hs +49/−0
- src/Data/Digit/Class/D5.hs +49/−0
- src/Data/Digit/Class/D6.hs +50/−0
- src/Data/Digit/Class/D7.hs +49/−0
- src/Data/Digit/Class/D8.hs +49/−0
- src/Data/Digit/Class/D9.hs +49/−0
- src/Data/Digit/Class/LowerCase.hs +214/−0
- src/Data/Digit/Class/MixedCase.hs +192/−0
- src/Data/Digit/Class/UpperCase.hs +213/−0
- src/Data/Digit/D0.hs +0/−9
- src/Data/Digit/D1.hs +0/−9
- src/Data/Digit/D2.hs +0/−9
- src/Data/Digit/D3.hs +0/−9
- src/Data/Digit/D4.hs +0/−9
- src/Data/Digit/D5.hs +0/−9
- src/Data/Digit/D6.hs +0/−9
- src/Data/Digit/D7.hs +0/−9
- src/Data/Digit/D8.hs +0/−9
- src/Data/Digit/D9.hs +0/−9
- src/Data/Digit/Decimal.hs +133/−0
- src/Data/Digit/Digit.hs +0/−272
- src/Data/Digit/Digit1_8.hs +0/−255
- src/Data/Digit/Digit1_9.hs +0/−239
- src/Data/Digit/Enum.hs +169/−0
- src/Data/Digit/Hexadecimal/LowerCase.hs +129/−0
- src/Data/Digit/Hexadecimal/MixedCase.hs +144/−0
- src/Data/Digit/Hexadecimal/UpperCase.hs +126/−0
- src/Data/Digit/Integral.hs +549/−0
- src/Data/Digit/Natural.hs +116/−0
- src/Data/Digit/Octal.hs +95/−0
- test/Main.hs +307/−0
- test/doctests.hs +0/−32
+ CONTRIBUTORS view
@@ -0,0 +1,33 @@+Tony Morris+tmorris@tmorris.net+http://tmorris.net/+-----BEGIN PGP PUBLIC KEY BLOCK-----+Version: GnuPG v1.4.6 (GNU/Linux)++mQGiBETNyC0RBAC3MYSZSbDZhBLKra2YUphB9OO6+qMFl/v2Lq8590ZfeE2WjIOu+c/KGKyOigXztMrA4+iekUjM4FA8E6AlBRQiAqZK8HF0ftX5hDpuSyEKkZe3jcxxI+BbhwX/SWHtDEVzwNmvO1wEnwhRE1oY/BCmy+bQ9wmAjlNav4UbOIcXcJUwCgz6FF+UwDvPxzybgd9FNS14BE37n8D/AzGmGjunBW/x+g/ndwu6WEpTEn1ZNdja6VrNXSG+xQ8XM+NBulroAIYX+YWdHsKnuGvSKCgVoc1ifVHdztA9sksID5GBGzhmVbIP2E16+w/LEzqqwruv9dX0Y1b7n8hcnvbl4DgEgLgeQ+VgJfLUkY2jFZ2m3dEBRH9USSgB/+V2pBBACP4Us2ZBYEXtMG29g6GqyeeJLEP34PLYVHWJZbet/wPQsHFhYahhzjwZGG+Srp0JUpegJOdaqX/Y0nio2whgCpqJcrbGuUBqNgQI3k4gvBwnPyx7jM0kfHfFORG+lq9SDbfLpV0EJx6fWXGStW33zsQQvenDcV2F5czzKQcy66BFwbQhVG9ueSBNb3Jy+aXMgPHRtb3JyaXNAdG1vcnJpcy5uZXQ+iGMEExECACMFAkTNyC0FCQlmAYAGCwkI+BwMCBBUCCAMEFgIDAQIeAQIXgAAKCRCaemCth7qvrf0pAKCFii2pI2W1BKVFuQcw+yoNxP0CAUACgyhuI9isCvtrOkeyjDmCVueRCdaC5Ag0ERM3IThAIAJ6A1z+d40ve+WvPIhpFiGfoS8UX4YdgYpo2mC/orY0xszBitogtaTHQHU5YDemGg81plNg9I3DbM+Er8uyONV4DqF6RbLj4w+iA6zn93+PTEZ73ydhxF6vDuojpVZPXVzXzpgyXHkEVLC+3hKL9oVlEsh+DWCvCiSAIy780JZ3FNVuMC3VH4qKxTw0CwPuuZvVfnMoIRfpODRR+fVEk2VDor+lr8kqJkBaHgN5o/AvOXC7QCYadwbEkpr0ecxIZ1VcASYytIIM3YNL7+ZcHWwU5PCNLOdMXPqOdthhDhsHkKJNEXXr0YsjX/bQqYOUqYKPDyqh/yrrRO9Ro6+7eTSbfIguycAAwcH/2waLIQR8qYKxPknNuSdsOOqF2jf2gglL/7uMsIzjfkFzgHo++GNHw9tmlZqD3yzaZ/N7Yv08ujRHhmWPBYAWRICBM3qo0zMJ9kI5XWRobeRQpLtf+YxxIOenq8R9t6YU9ryHdqf+P+Fi38eN5ERTDhNLrJOnO5/TA+of97BWCmdtJMlWM+RaHtqXxwo02Yi65IqKx6L7oOvT7Gh4NV2eglz8ZafPEoP8+V8ER7rwBYPiLk4Mse+oVImjveq2dmLUip9OPwznoaeyC8zB0mJ13m/KNC+CffkBgoXpMPiKzbu5YTjVw+++MlEmfgL42yDK0hnokmW2i9y1RBh/T1VQQeQbUaeITAQYEQIADAUCRM3ITgUJCWYB+gAAKCRCaemCth7qvrcbtAJ9j3C6lKNRB3uKcrfze66jAVQh0qACaAysOK82TcQ/2+73ryR0xWMFnpGqg=+=bMTb+-----END PGP PUBLIC KEY BLOCK-----
+ LICENCE view
@@ -0,0 +1,33 @@+Copyright (C) 2010-2016 NICTA Limited+Copyright (c) 2017-2018, Commonwealth Scientific and Industrial Research Organisation+(CSIRO) ABN 41 687 119 230.+Copyright (c) 2019-2020, System F (System F Aerial Operations) ABN 19 363 313 255++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 System F 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.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
− Setup.lhs
@@ -1,44 +0,0 @@-#!/usr/bin/env runhaskell-\begin{code}-{-# OPTIONS_GHC -Wall #-}-module Main (main) where--import Data.List ( nub )-import Data.Version ( showVersion )-import Distribution.Package ( PackageName(PackageName), PackageId, InstalledPackageId, packageVersion, packageName )-import Distribution.PackageDescription ( PackageDescription(), TestSuite(..) )-import Distribution.Simple ( defaultMainWithHooks, UserHooks(..), simpleUserHooks )-import Distribution.Simple.Utils ( rewriteFile, createDirectoryIfMissingVerbose )-import Distribution.Simple.BuildPaths ( autogenModulesDir )-import Distribution.Simple.Setup ( BuildFlags(buildVerbosity), fromFlag )-import Distribution.Simple.LocalBuildInfo ( withLibLBI, withTestLBI, LocalBuildInfo(), ComponentLocalBuildInfo(componentPackageDeps) )-import Distribution.Verbosity ( Verbosity )-import System.FilePath ( (</>) )--main :: IO ()-main = defaultMainWithHooks simpleUserHooks- { buildHook = \pkg lbi hooks flags -> do- generateBuildModule (fromFlag (buildVerbosity flags)) pkg lbi- buildHook simpleUserHooks pkg lbi hooks flags- }--generateBuildModule :: Verbosity -> PackageDescription -> LocalBuildInfo -> IO ()-generateBuildModule verbosity pkg lbi = do- let dir = autogenModulesDir lbi- createDirectoryIfMissingVerbose verbosity True dir- withLibLBI pkg lbi $ \_ libcfg -> do- withTestLBI pkg lbi $ \suite suitecfg -> do- rewriteFile (dir </> "Build_" ++ testName suite ++ ".hs") $ unlines- [ "module Build_" ++ testName suite ++ " where"- , "deps :: [String]"- , "deps = " ++ (show $ formatdeps (testDeps libcfg suitecfg))- ]- where- formatdeps = map (formatone . snd)- formatone p = case packageName p of- PackageName n -> n ++ "-" ++ showVersion (packageVersion p)--testDeps :: ComponentLocalBuildInfo -> ComponentLocalBuildInfo -> [(InstalledPackageId, PackageId)]-testDeps xs ys = nub $ componentPackageDeps xs ++ componentPackageDeps ys--\end{code}
+ changelog.md view
@@ -0,0 +1,117 @@+0.15++* Widen version bounds.++0.14++* Fix export for `DecDigitNoZero`.++0.13++* Make `DecDigitNoZero` data type.++0.12++* Fix bug in functions that produce Integral values.++0.11++* Update `lens` to support `< 5.2`++0.9++* Update base version.++0.8++* Add decimal arithmetic++0.6++* Removed the `Digit` datatype+* Added new datatypes with appropriate `D*` instances+ * `BinDigit`+ * `OctDigit`+ * `DecDigit`+ * `HexDigit`+ * `HeXDigit`+ * `HEXDigit`+* Culled most of the doctests, and leaving one or two per function to illustrate+ usage+* Juggled re-exports to make the library easier to use and to improve documentation+* Added `Data.Digit.Enum`, which contains ascending-order enumerations of the new datatypes+* Added integral conversion functions for the new datatypes++0.5.3++* Bump version of [tasty-hedgehog, hedgehog, papa]+* Updated default.nix++0.5.2++* Add `Data.Digit.Natural (_NaturalDigits, naturalToDigits, digitsToNatural)`++0.5.1++* Replace doctest with hunit and hedgehog via tasty++0.5.0++* Data types for other bases (binary, octal, hexadecimal).+* Remove the `Digit…` data types.+* Introduce the `Digit` data type.++0.4.0++* Refactor to classy prisms for each digit.++0.3.0++* Refactor decimal type.+* `Digits` and `Digits1` data types for list of digits.++0.2.9++* Remove redundant type-class constraints.+* Add tests.+* Add `HasDigit` lens.+* Add `papa` dependency.++0.2.8++* Add `(/+/)` function.++0.2.7++* Add `mantissa` function for digits.++0.2.6++* Use `Integral` not `Int`.+* `Digits` data type (zero or many digits) and associated functions.++0.2.5++* Change parser to handle non-empty list.++0.2.4++* More Digit parsers.++0.2.3++* Digit parsers.++0.2.2++* Modulus operations.+* `digits` function.+* Fix tests.++0.2.1++* Include digit parsers.++0.2.0++* Update to use digit prisms.
digit.cabal view
@@ -1,80 +1,114 @@ name: digit-version: 0.1.2+version: 0.15 license: BSD3-license-File: etc/LICENCE-author: Tony Morris <ʇǝu˙sıɹɹoɯʇ@ןןǝʞsɐɥ>-maintainer: Tony Morris-copyright: Copyright (C) 2010-2013 NICTA Limited+license-file: LICENCE+author: System F <nɐ˙ɯoɔ˙ɟɯǝʇsʎs@ǝpoɔ>+maintainer: System F <nɐ˙ɯoɔ˙ɟɯǝʇsʎs@ǝpoɔ>+copyright: Copyright (c) 2010-2016 NICTA Limited+ Copyright (c) 2017-2018, Commonwealth Scientific and Industrial Research Organisation (CSIRO) ABN 41 687 119 230.+ Copyright (c) System F (System F Aerial Operations) 2019-2020 synopsis: A data-type representing digits 0-9 and other combinations category: Data-homepage: https://github.com/NICTA/digit-bug-reports: https://github.com/NICTA/digit/issues+homepage: https://github.com/system-f/digit+bug-reports: https://github.com/system-f/digit/issues cabal-version: >= 1.10-build-type: Custom-extra-source-files: etc/CONTRIBUTORS+build-type: Simple+extra-source-files: CONTRIBUTORS, changelog.md+tested-with: GHC == 9.8.1, GHC == 9.6.3, GHC == 9.4.7, GHC == 9.0.2, GHC == 8.6.1, GHC == 8.4.3, GHC == 8.2.2, GHC == 8.0.2, GHC == 7.10.3 description:- <<http://i.imgur.com/Ns5hntl.jpg>>+ <<https://system-f.gitlab.io/logo/systemf-450x450.jpg>> . @Digit@ is a data-type that represents the digits 0-9 and other combinations. source-repository head type: git- location: git@github.com:NICTA/digit.git--flag small_base- description: Choose the new, split-up base package.+ location: git@github.com:system-f/digit.git library default-language: Haskell2010 build-depends:- base < 5 && >= 3- , lens >= 3.9.2- , template-haskell+ base >= 4.8 && < 6+ , lens >= 4.0 && < 6+ , parsers >= 0.12.3 && < 1+ , semigroups >= 0.12 && < 1.0+ , template-haskell >= 2.8 && < 3+ , semigroupoids >= 5 && < 7+ , scientific >= 0.3 && < 1 ghc-options: -Wall + default-extensions:+ NoImplicitPrelude+ hs-source-dirs: src exposed-modules: Data.Digit- Data.Digit.D0- Data.Digit.D1- Data.Digit.D2- Data.Digit.D3- Data.Digit.D4- Data.Digit.D5- Data.Digit.D6- Data.Digit.D7- Data.Digit.D8- Data.Digit.D9- Data.Digit.Digit- Data.Digit.Digit1_8- Data.Digit.Digit1_9+ Data.Digit.Binary+ Data.Digit.Natural+ Data.Digit.Decimal+ Data.Digit.Octal -test-suite doctests+ Data.Digit.Hexadecimal.LowerCase+ Data.Digit.Hexadecimal.UpperCase+ Data.Digit.Hexadecimal.MixedCase++ Data.Digit.Class.D0+ Data.Digit.Class.D1+ Data.Digit.Class.D2+ Data.Digit.Class.D3+ Data.Digit.Class.D4+ Data.Digit.Class.D5+ Data.Digit.Class.D6+ Data.Digit.Class.D7+ Data.Digit.Class.D8+ Data.Digit.Class.D9++ Data.Digit.Class.LowerCase+ Data.Digit.Class.MixedCase+ Data.Digit.Class.UpperCase++ Data.Digit.Char+ Data.Digit.Enum+ Data.Digit.Integral+++test-suite tests type: exitcode-stdio-1.0 main-is:- doctests.hs+ Main.hs default-language: Haskell2010 build-depends:- base < 5 && >= 3,- doctest >= 0.9.7,- filepath >= 1.3,- directory >= 1.1,- QuickCheck >= 2.0+ base >=4.8 && <4.13+ , lens >=4.0 && <5.2+ , ansi-wl-pprint >=0.6 && <0.7+ , hedgehog >=0.5 && <1.1+ , tasty >=0.11 && <1.3+ , tasty-hspec >=1.1 && <1.2+ , parsec >=3.1 && <3.2+ , parsers >=0.12.3 && <0.13+ , pretty >=1.1 && <1.2+ , text >=1.2 && <1.3+ , tasty-hedgehog >=0.1 && <1.1+ , tasty-hunit >=0.9 && <0.11+ , semigroups >= 0.12 && < 1.0+ , digit ghc-options: -Wall -threaded++ default-extensions:+ NoImplicitPrelude hs-source-dirs: test
− etc/CONTRIBUTORS
@@ -1,33 +0,0 @@-Tony Morris-tmorris@tmorris.net-http://tmorris.net/------BEGIN PGP PUBLIC KEY BLOCK------Version: GnuPG v1.4.6 (GNU/Linux)--mQGiBETNyC0RBAC3MYSZSbDZhBLKra2YUphB9OO6+qMFl/v2Lq8590ZfeE2WjIOu-c/KGKyOigXztMrA4+iekUjM4FA8E6AlBRQiAqZK8HF0ftX5hDpuSyEKkZe3jcxxI-BbhwX/SWHtDEVzwNmvO1wEnwhRE1oY/BCmy+bQ9wmAjlNav4UbOIcXcJUwCgz6FF-UwDvPxzybgd9FNS14BE37n8D/AzGmGjunBW/x+g/ndwu6WEpTEn1ZNdja6VrNXSG-xQ8XM+NBulroAIYX+YWdHsKnuGvSKCgVoc1ifVHdztA9sksID5GBGzhmVbIP2E16-w/LEzqqwruv9dX0Y1b7n8hcnvbl4DgEgLgeQ+VgJfLUkY2jFZ2m3dEBRH9USSgB/-V2pBBACP4Us2ZBYEXtMG29g6GqyeeJLEP34PLYVHWJZbet/wPQsHFhYahhzjwZGG-Srp0JUpegJOdaqX/Y0nio2whgCpqJcrbGuUBqNgQI3k4gvBwnPyx7jM0kfHfFORG-lq9SDbfLpV0EJx6fWXGStW33zsQQvenDcV2F5czzKQcy66BFwbQhVG9ueSBNb3Jy-aXMgPHRtb3JyaXNAdG1vcnJpcy5uZXQ+iGMEExECACMFAkTNyC0FCQlmAYAGCwkI-BwMCBBUCCAMEFgIDAQIeAQIXgAAKCRCaemCth7qvrf0pAKCFii2pI2W1BKVFuQcw-yoNxP0CAUACgyhuI9isCvtrOkeyjDmCVueRCdaC5Ag0ERM3IThAIAJ6A1z+d40ve-WvPIhpFiGfoS8UX4YdgYpo2mC/orY0xszBitogtaTHQHU5YDemGg81plNg9I3DbM-Er8uyONV4DqF6RbLj4w+iA6zn93+PTEZ73ydhxF6vDuojpVZPXVzXzpgyXHkEVLC-3hKL9oVlEsh+DWCvCiSAIy780JZ3FNVuMC3VH4qKxTw0CwPuuZvVfnMoIRfpODRR-fVEk2VDor+lr8kqJkBaHgN5o/AvOXC7QCYadwbEkpr0ecxIZ1VcASYytIIM3YNL7-ZcHWwU5PCNLOdMXPqOdthhDhsHkKJNEXXr0YsjX/bQqYOUqYKPDyqh/yrrRO9Ro6-7eTSbfIguycAAwcH/2waLIQR8qYKxPknNuSdsOOqF2jf2gglL/7uMsIzjfkFzgHo-+GNHw9tmlZqD3yzaZ/N7Yv08ujRHhmWPBYAWRICBM3qo0zMJ9kI5XWRobeRQpLtf-YxxIOenq8R9t6YU9ryHdqf+P+Fi38eN5ERTDhNLrJOnO5/TA+of97BWCmdtJMlWM-RaHtqXxwo02Yi65IqKx6L7oOvT7Gh4NV2eglz8ZafPEoP8+V8ER7rwBYPiLk4Mse-oVImjveq2dmLUip9OPwznoaeyC8zB0mJ13m/KNC+CffkBgoXpMPiKzbu5YTjVw++-MlEmfgL42yDK0hnokmW2i9y1RBh/T1VQQeQbUaeITAQYEQIADAUCRM3ITgUJCWYB-gAAKCRCaemCth7qvrcbtAJ9j3C6lKNRB3uKcrfze66jAVQh0qACaAysOK82TcQ/2-73ryR0xWMFnpGqg=-=bMTb------END PGP PUBLIC KEY BLOCK-----
− etc/LICENCE
@@ -1,27 +0,0 @@-Copyright 2013 NICTA Limited--All rights reserved.--Redistribution and use in source and binary forms, with or without-modification, are permitted provided that the following conditions-are met:-1. Redistributions of source code must retain the above copyright- notice, this list of conditions and the following disclaimer.-2. 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.-3. Neither the name of the author nor the names of his contributors- may be used to endorse or promote products derived from this software- without specific prior written permission.--THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 AUTHORS 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.
src/Data/Digit.hs view
@@ -1,15 +1,26 @@-module Data.Digit(module D) where+{-# LANGUAGE NoImplicitPrelude #-} -import Data.Digit.D0 as D-import Data.Digit.D1 as D-import Data.Digit.D2 as D-import Data.Digit.D3 as D-import Data.Digit.D4 as D-import Data.Digit.D5 as D-import Data.Digit.D6 as D-import Data.Digit.D7 as D-import Data.Digit.D8 as D-import Data.Digit.D9 as D-import Data.Digit.Digit as D-import Data.Digit.Digit1_8 as D-import Data.Digit.Digit1_9 as D+module Data.Digit (+ module Data.Digit.Binary+, module Data.Digit.Decimal+, module Data.Digit.Octal+, module Data.Digit.Hexadecimal.LowerCase+, module Data.Digit.Hexadecimal.UpperCase+, module Data.Digit.Hexadecimal.MixedCase+-- * Utilities+, module Data.Digit.Char+, module Data.Digit.Enum+, module Data.Digit.Integral+, module Data.Digit.Natural+) where++import Data.Digit.Binary+import Data.Digit.Decimal+import Data.Digit.Octal+import Data.Digit.Hexadecimal.LowerCase+import Data.Digit.Hexadecimal.UpperCase+import Data.Digit.Hexadecimal.MixedCase+import Data.Digit.Char+import Data.Digit.Enum+import Data.Digit.Integral+import Data.Digit.Natural
+ src/Data/Digit/Binary.hs view
@@ -0,0 +1,57 @@+{-# LANGUAGE NoImplicitPrelude #-}+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE TemplateHaskell #-}++module Data.Digit.Binary(+ BinDigit(..)+, BinaryNoZero+, Binary+, parseBinaryNoZero+, parseBinary+-- * Prisms+, _BinDigit0+, _BinDigit1+-- * Re-exports+, module Data.Digit.Class.D0+, module Data.Digit.Class.D1+) where++import Prelude (Eq, Show, Ord)+import Control.Lens.TH (makePrisms)+import Text.Parser.Char(CharParsing)+import Text.Parser.Combinators((<?>), choice)++import Data.Digit.Class.D0+import Data.Digit.Class.D1++data BinDigit+ = BinDigit0+ | BinDigit1+ deriving (Show, Eq, Ord)++makePrisms ''BinDigit++instance D0 BinDigit where; d0 = _BinDigit0+instance D1 BinDigit where; d1 = _BinDigit1++type BinaryNoZero d =+ D1 d++parseBinaryNoZero ::+ (BinaryNoZero d, CharParsing p) =>+ p d+parseBinaryNoZero =+ parse1 <?> "BinaryNoZero"++type Binary d =+ (D0 d, BinaryNoZero d)++parseBinary ::+ (Binary d, CharParsing p) =>+ p d+parseBinary =+ choice+ [+ parse0+ , parseBinaryNoZero+ ] <?> "Binary"
+ src/Data/Digit/Char.hs view
@@ -0,0 +1,239 @@+{-# LANGUAGE NoImplicitPrelude #-}++module Data.Digit.Char(+-- * Binary+ charBinaryNoZero+, charBinary+-- * Octal+, charOctalNoZero+, charOctal+-- * Decimal+, charDecimalNoZero+, charDecimal+-- * Hexadecimal+, charHexadecimalNoZero+, charHexadecimal+-- * HEXADECIMAL+, charHEXADECIMALNoZero+, charHEXADECIMAL+-- * HeXaDeCiMaL+, charHeXaDeCiMaLNoZero+, charHeXaDeCiMaL+) where++import Prelude (Char, Eq, fst, lookup)++import Control.Applicative (Applicative)+import Control.Lens (APrism, Choice, Prism', clonePrism,+ prism', ( # ))+import Control.Lens.Extras (is)++import Data.Foldable (find)+import Data.Functor ((<$>))+import Data.Maybe (fromMaybe)++import Data.Digit.Binary as D+import Data.Digit.Decimal as D+import Data.Digit.Hexadecimal.LowerCase as D+import Data.Digit.Hexadecimal.UpperCase as D+import Data.Digit.Hexadecimal.MixedCase as D+import Data.Digit.Octal as D++-- $setup+-- >>> import Data.Digit++-- |+--+-- >>> '1' ^? charBinaryNoZero :: Maybe BinDigit+-- Just BinDigit1+--+-- >>> charBinaryNoZero # BinDigit1+-- '1'+charBinaryNoZero ::+ BinaryNoZero d =>+ Prism'+ Char+ d+charBinaryNoZero =+ associatePrism ('1', d1) []++-- |+--+-- >>> '0' ^? charBinary :: Maybe BinDigit+-- Just BinDigit0+--+-- >>> charBinary # BinDigit0 :: Char+-- '0'+charBinary ::+ Binary d =>+ Prism'+ Char+ d+charBinary =+ associatePrism ('0', d0) [('1', d1)]++-- |+--+-- >>> '6' ^? charOctalNoZero :: Maybe OctDigit+-- Just OctDigit6+--+-- >>> charOctalNoZero # OctDigit5 :: Char+-- '5'+charOctalNoZero ::+ OctalNoZero d =>+ Prism'+ Char+ d+charOctalNoZero =+ associatePrism ('1', d1) [('2', d2), ('3', d3), ('4', d4), ('5', d5), ('6', d6), ('7', d7)]++-- |+-- >>> '7' ^? charOctal :: Maybe OctDigit+-- Just OctDigit7+--+-- >>> charOctal # OctDigit7 :: Char+-- '7'+charOctal ::+ Octal d =>+ Prism'+ Char+ d+charOctal =+ associatePrism ('0', d0) [('1', d1), ('2', d2), ('3', d3), ('4', d4), ('5', d5), ('6', d6), ('7', d7)]++-- |+-- >>> '9' ^? charDecimalNoZero :: Maybe DecDigit+-- Just DecDigit9+--+-- >>> charDecimalNoZero # DecDigit9 :: Char+-- '9'+charDecimalNoZero ::+ DecimalNoZero d =>+ Prism'+ Char+ d+charDecimalNoZero =+ associatePrism ('1', d1) [('2', d2), ('3', d3), ('4', d4), ('5', d5), ('6', d6), ('7', d7), ('8', d8), ('9', d9)]++-- |+-- >>> '9' ^? charDecimal :: Maybe DecDigit+-- Just DecDigit9+--+-- >>> charDecimal # DecDigit9 :: Char+-- '9'+charDecimal ::+ Decimal d =>+ Prism'+ Char+ d+charDecimal =+ associatePrism ('0', d0) [('1', d1), ('2', d2), ('3', d3), ('4', d4), ('5', d5), ('6', d6), ('7', d7), ('8', d8), ('9', d9)]++-- |+-- >>> 'f' ^? charHexadecimalNoZero :: Maybe HexDigit+-- Just HexDigitf+--+-- >>> charHexadecimalNoZero # HexDigitf :: Char+-- 'f'+charHexadecimalNoZero ::+ HexadecimalNoZero d =>+ Prism'+ Char+ d+charHexadecimalNoZero =+ associatePrism ('1', d1) [('2', d2), ('3', d3), ('4', d4), ('5', d5), ('6', d6), ('7', d7), ('8', d8), ('9', d9), ('a', da), ('b', db), ('c', dc), ('d', dd), ('e', de), ('f', df)]++-- |+-- >>> 'f' ^? charHexadecimal :: Maybe HexDigit+-- Just HexDigitf+--+-- >>> charHexadecimal # HexDigitf :: Char+-- 'f'+charHexadecimal ::+ Hexadecimal d =>+ Prism'+ Char+ d+charHexadecimal =+ associatePrism ('0', d0) [('1', d1), ('2', d2), ('3', d3), ('4', d4), ('5', d5), ('6', d6), ('7', d7), ('8', d8), ('9', d9), ('a', da), ('b', db), ('c', dc), ('d', dd), ('e', de), ('f', df)]++-- |+-- >>> 'F' ^? charHEXADECIMALNoZero :: Maybe HEXDigit+-- Just HEXDigitF+--+-- >>> charHEXADECIMALNoZero # HEXDigitF :: Char+-- 'F'+charHEXADECIMALNoZero ::+ HEXADECIMALNoZero d =>+ Prism'+ Char+ d+charHEXADECIMALNoZero =+ associatePrism ('1', d1) [('2', d2), ('3', d3), ('4', d4), ('5', d5), ('6', d6), ('7', d7), ('8', d8), ('9', d9), ('A', dA), ('B', dB), ('C', dC), ('D', dD), ('E', dE), ('F', dF)]++-- |+-- >>> 'F' ^? charHEXADECIMAL :: Maybe HEXDigit+-- Just HEXDigitF+--+-- >>> charHEXADECIMAL # HEXDigitF :: Char+-- 'F'+charHEXADECIMAL ::+ HEXADECIMAL d =>+ Prism'+ Char+ d+charHEXADECIMAL =+ associatePrism ('0', d0) [('1', d1), ('2', d2), ('3', d3), ('4', d4), ('5', d5), ('6', d6), ('7', d7), ('8', d8), ('9', d9), ('A', dA), ('B', dB), ('C', dC), ('D', dD), ('E', dE), ('F', dF)]++-- |+-- >>> 'f' ^? charHeXaDeCiMaLNoZero :: Maybe HeXDigit+-- Just HeXDigitf+--+-- >>> 'F' ^? charHeXaDeCiMaLNoZero :: Maybe HeXDigit+-- Just HeXDigitF+--+-- >>> charHeXaDeCiMaLNoZero # HeXDigitf :: Char+-- 'f'+--+-- >>> charHeXaDeCiMaLNoZero # HeXDigitF :: Char+-- 'F'+charHeXaDeCiMaLNoZero ::+ HeXaDeCiMaLNoZero d =>+ Prism'+ Char+ d+charHeXaDeCiMaLNoZero =+ associatePrism ('1', d1) [('2', d2), ('3', d3), ('4', d4), ('5', d5), ('6', d6), ('7', d7), ('8', d8), ('9', d9), ('a', da), ('b', db), ('c', dc), ('d', dd), ('e', de), ('f', df), ('A', dA), ('B', dB), ('C', dC), ('D', dD), ('E', dE), ('F', dF)]+++-- |+-- >>> 'f' ^? charHeXaDeCiMaL :: Maybe HeXDigit+-- Just HeXDigitf+--+-- >>> 'F' ^? charHeXaDeCiMaL :: Maybe HeXDigit+-- Just HeXDigitF+--+-- >>> charHeXaDeCiMaL # HeXDigitf :: Char+-- 'f'+--+-- >>> charHeXaDeCiMaL # HeXDigitF :: Char+-- 'F'+charHeXaDeCiMaL ::+ HeXaDeCiMaL d =>+ Prism'+ Char+ d+charHeXaDeCiMaL =+ associatePrism ('0', d0) [('1', d1), ('2', d2), ('3', d3), ('4', d4), ('5', d5), ('6', d6), ('7', d7), ('8', d8), ('9', d9), ('a', da), ('b', db), ('c', dc), ('d', dd), ('e', de), ('f', df), ('A', dA), ('B', dB), ('C', dC), ('D', dD), ('E', dE), ('F', dF)]++---- not exported+associatePrism ::+ (Eq b, Choice p, Applicative f) =>+ (b, APrism a a () ())+ -> [(b, APrism a a () ())]+ -> p a (f a)+ -> p b (f b)+associatePrism def z =+ prism'+ (\d -> fst (fromMaybe def (find (\(_, w) -> is w d) z)))+ (\i -> (\p -> clonePrism p # ()) <$> lookup i (def:z))
+ src/Data/Digit/Class/D0.hs view
@@ -0,0 +1,50 @@+{-# LANGUAGE NoImplicitPrelude #-}+{-# LANGUAGE FlexibleInstances #-}++module Data.Digit.Class.D0(+ D0(..)+, parse0+) where++import Control.Category (id)+import Control.Lens (Prism', (#))++import Data.Functor ((<$))++import Text.Parser.Char(CharParsing, char)+import Text.Parser.Combinators((<?>))++-- $setup+-- >>> import Data.Digit.Class+-- >>> import Text.Parsec(parse, ParseError, eof)+-- >>> import Data.Void(Void)++class D0 d where+ d0 ::+ Prism'+ d+ ()+ x0 ::+ d+ x0 =+ d0 # ()++instance D0 () where+ d0 =+ id++-- |+--+-- >>> parse (parse0 <* eof) "test" "0" :: Either ParseError BinDigit+-- Right BinDigit0+--+-- >>> parse parse0 "test" "0xyz" :: Either ParseError BinDigit+-- Right BinDigit0+--+-- >>> isn't _Right (parse parse0 "test" "xyz" :: Either ParseError BinDigit)+-- True+parse0 ::+ (D0 d, CharParsing p) =>+ p d+parse0 =+ x0 <$ char '0' <?> "0"
+ src/Data/Digit/Class/D1.hs view
@@ -0,0 +1,49 @@+{-# LANGUAGE NoImplicitPrelude #-}++module Data.Digit.Class.D1(+ D1(..)+, parse1+) where++import Control.Category (id)+import Control.Lens (Prism', (#))++import Data.Functor ((<$))++import Text.Parser.Char(CharParsing, char)+import Text.Parser.Combinators((<?>))++-- $setup+-- >>> import Data.Digit.Class+-- >>> import Text.Parsec(parse, ParseError, eof)+-- >>> import Data.Void(Void)++class D1 d where+ d1 ::+ Prism'+ d+ ()+ x1 ::+ d+ x1 =+ d1 # ()++instance D1 () where+ d1 =+ id++-- |+--+-- >>> parse (parse1 <* eof) "test" "1" :: Either ParseError BinDigit+-- Right BinDigit1+--+-- >>> parse parse1 "test" "1xyz" :: Either ParseError BinDigit+-- Right BinDigit1+--+-- >>> isn't _Right (parse parse1 "test" "xyz" :: Either ParseError BinDigit)+-- True+parse1 ::+ (D1 d, CharParsing p) =>+ p d+parse1 =+ x1 <$ char '1' <?> "1"
+ src/Data/Digit/Class/D2.hs view
@@ -0,0 +1,49 @@+{-# LANGUAGE NoImplicitPrelude #-}++module Data.Digit.Class.D2(+ D2(..)+, parse2+) where++import Control.Category (id)+import Control.Lens (Prism', (#))++import Data.Functor ((<$))++import Text.Parser.Char(CharParsing, char)+import Text.Parser.Combinators((<?>))++-- $setup+-- >>> import Data.Digit.Class+-- >>> import Text.Parsec(parse, ParseError, eof)+-- >>> import Data.Void(Void)++class D2 d where+ d2 ::+ Prism'+ d+ ()+ x2 ::+ d+ x2 =+ d2 # ()++instance D2 () where+ d2 =+ id+ +-- |+--+-- >>> parse (parse2 <* eof) "test" "2" :: Either ParseError DecDigit+-- Right DecDigit2+--+-- >>> parse parse2 "test" "2xyz" :: Either ParseError DecDigit+-- Right DecDigit2+--+-- >>> isn't _Right (parse parse2 "test" "xyz" :: Either ParseError DecDigit)+-- True+parse2 ::+ (D2 d, CharParsing p) =>+ p d+parse2 =+ x2 <$ char '2' <?> "2"
+ src/Data/Digit/Class/D3.hs view
@@ -0,0 +1,49 @@+{-# LANGUAGE NoImplicitPrelude #-}++module Data.Digit.Class.D3(+ D3(..)+, parse3+) where++import Control.Category (id)+import Control.Lens (Prism', (#))++import Data.Functor ((<$))++import Text.Parser.Char(CharParsing, char)+import Text.Parser.Combinators((<?>))++-- $setup+-- >>> import Data.Digit.Class+-- >>> import Text.Parsec(parse, ParseError, eof)+-- >>> import Data.Void(Void)++class D3 d where+ d3 ::+ Prism'+ d+ ()+ x3 ::+ d+ x3 =+ d3 # ()++instance D3 () where+ d3 =+ id++-- |+--+-- >>> parse (parse3 <* eof) "test" "3" :: Either ParseError DecDigit+-- Right DecDigit3+--+-- >>> parse parse3 "test" "3xyz" :: Either ParseError DecDigit+-- Right DecDigit3+--+-- >>> isn't _Right (parse parse3 "test" "xyz" :: Either ParseError DecDigit)+-- True+parse3 ::+ (D3 d, CharParsing p) =>+ p d+parse3 =+ x3 <$ char '3' <?> "3"
+ src/Data/Digit/Class/D4.hs view
@@ -0,0 +1,49 @@+{-# LANGUAGE NoImplicitPrelude #-}++module Data.Digit.Class.D4(+ D4(..)+, parse4+) where++import Control.Category (id)+import Control.Lens (Prism', (#))++import Data.Functor ((<$))++import Text.Parser.Char(CharParsing, char)+import Text.Parser.Combinators((<?>))++-- $setup+-- >>> import Data.Digit.Class+-- >>> import Text.Parsec(parse, ParseError, eof)+-- >>> import Data.Void(Void)++class D4 d where+ d4 ::+ Prism'+ d+ ()+ x4 ::+ d+ x4 =+ d4 # ()++instance D4 () where+ d4 =+ id+ +-- |+--+-- >>> parse (parse4 <* eof) "test" "4" :: Either ParseError DecDigit+-- Right DecDigit4+--+-- >>> parse parse4 "test" "4xyz" :: Either ParseError DecDigit+-- Right DecDigit4+--+-- >>> isn't _Right (parse parse4 "test" "xyz" :: Either ParseError DecDigit)+-- True+parse4 ::+ (D4 d, CharParsing p) =>+ p d+parse4 =+ x4 <$ char '4' <?> "4"
+ src/Data/Digit/Class/D5.hs view
@@ -0,0 +1,49 @@+{-# LANGUAGE NoImplicitPrelude #-}++module Data.Digit.Class.D5(+ D5(..)+, parse5+) where++import Control.Category (id)+import Control.Lens (Prism', (#))++import Data.Functor ((<$))++import Text.Parser.Char(CharParsing, char)+import Text.Parser.Combinators((<?>))++-- $setup+-- >>> import Data.Digit.Class+-- >>> import Text.Parsec(parse, ParseError, eof)+-- >>> import Data.Void(Void)++class D5 d where+ d5 ::+ Prism'+ d+ ()+ x5 ::+ d+ x5 =+ d5 # ()++instance D5 () where+ d5 =+ id+ +-- |+--+-- >>> parse (parse5 <* eof) "test" "5" :: Either ParseError DecDigit+-- Right DecDigit5+--+-- >>> parse parse5 "test" "5xyz" :: Either ParseError DecDigit+-- Right DecDigit5+--+-- >>> isn't _Right (parse parse5 "test" "xyz" :: Either ParseError DecDigit)+-- True+parse5 ::+ (D5 d, CharParsing p) =>+ p d+parse5 =+ x5 <$ char '5' <?> "5"
+ src/Data/Digit/Class/D6.hs view
@@ -0,0 +1,50 @@+{-# LANGUAGE NoImplicitPrelude #-}++module Data.Digit.Class.D6(+ D6(..)+, parse6+) where+++import Control.Category (id)+import Control.Lens (Prism', (#))++import Data.Functor ((<$))++import Text.Parser.Char(CharParsing, char)+import Text.Parser.Combinators((<?>))++-- $setup+-- >>> import Data.Digit.Class+-- >>> import Text.Parsec(parse, ParseError, eof)+-- >>> import Data.Void(Void)++class D6 d where+ d6 ::+ Prism'+ d+ ()+ x6 ::+ d+ x6 =+ d6 # ()++instance D6 () where+ d6 =+ id+ +-- |+--+-- >>> parse (parse6 <* eof) "test" "6" :: Either ParseError DecDigit+-- Right DecDigit6+--+-- >>> parse parse6 "test" "6xyz" :: Either ParseError DecDigit+-- Right DecDigit6+--+-- >>> isn't _Right (parse parse6 "test" "xyz" :: Either ParseError DecDigit)+-- True+parse6 ::+ (D6 d, CharParsing p) =>+ p d+parse6 =+ x6 <$ char '6' <?> "6"
+ src/Data/Digit/Class/D7.hs view
@@ -0,0 +1,49 @@+{-# LANGUAGE NoImplicitPrelude #-}++module Data.Digit.Class.D7(+ D7(..)+, parse7+) where++import Control.Category (id)+import Control.Lens (Prism', (#))++import Data.Functor ((<$))++import Text.Parser.Char(CharParsing, char)+import Text.Parser.Combinators((<?>))++-- $setup+-- >>> import Data.Digit.Class+-- >>> import Text.Parsec(parse, ParseError, eof)+-- >>> import Data.Void(Void)++class D7 d where+ d7 ::+ Prism'+ d+ ()+ x7 ::+ d+ x7 =+ d7 # ()++instance D7 () where+ d7 =+ id+ +-- |+--+-- >>> parse (parse7 <* eof) "test" "7" :: Either ParseError DecDigit+-- Right DecDigit7+--+-- >>> parse parse7 "test" "7xyz" :: Either ParseError DecDigit+-- Right DecDigit7+--+-- >>> isn't _Right (parse parse7 "test" "xyz" :: Either ParseError DecDigit)+-- True+parse7 ::+ (D7 d, CharParsing p) =>+ p d+parse7 =+ x7 <$ char '7' <?> "7"
+ src/Data/Digit/Class/D8.hs view
@@ -0,0 +1,49 @@+{-# LANGUAGE NoImplicitPrelude #-}++module Data.Digit.Class.D8(+ D8(..)+, parse8+) where++import Control.Category (id)+import Control.Lens (Prism', (#))++import Data.Functor ((<$))++import Text.Parser.Char(CharParsing, char)+import Text.Parser.Combinators((<?>))++-- $setup+-- >>> import Data.Digit.Class+-- >>> import Text.Parsec(parse, ParseError, eof)+-- >>> import Data.Void(Void)++class D8 d where+ d8 ::+ Prism'+ d+ ()+ x8 ::+ d+ x8 =+ d8 # ()++instance D8 () where+ d8 =+ id+ +-- |+--+-- >>> parse (parse8 <* eof) "test" "8" :: Either ParseError DecDigit+-- Right DecDigit8+--+-- >>> parse parse8 "test" "8xyz" :: Either ParseError DecDigit+-- Right DecDigit8+--+-- >>> isn't _Right (parse parse8 "test" "xyz" :: Either ParseError DecDigit)+-- True+parse8 ::+ (D8 d, CharParsing p) =>+ p d+parse8 =+ x8 <$ char '8' <?> "8"
+ src/Data/Digit/Class/D9.hs view
@@ -0,0 +1,49 @@+{-# LANGUAGE NoImplicitPrelude #-}++module Data.Digit.Class.D9(+ D9(..)+, parse9+) where++import Control.Category (id)+import Control.Lens (Prism', (#))++import Data.Functor ((<$))++import Text.Parser.Char(CharParsing, char)+import Text.Parser.Combinators((<?>))++-- $setup+-- >>> import Data.Digit.Class+-- >>> import Text.Parsec(parse, ParseError, eof)+-- >>> import Data.Void(Void)++class D9 d where+ d9 ::+ Prism'+ d+ ()+ x9 ::+ d+ x9 =+ d9 # ()++instance D9 () where+ d9 =+ id+ +-- |+--+-- >>> parse (parse9 <* eof) "test" "9" :: Either ParseError DecDigit+-- Right DecDigit9+--+-- >>> parse parse9 "test" "9xyz" :: Either ParseError DecDigit+-- Right DecDigit9+--+-- >>> isn't _Right (parse parse9 "test" "xyz" :: Either ParseError DecDigit)+-- True+parse9 ::+ (D9 d, CharParsing p) =>+ p d+parse9 =+ x9 <$ char '9' <?> "9"
+ src/Data/Digit/Class/LowerCase.hs view
@@ -0,0 +1,214 @@+{-# LANGUAGE NoImplicitPrelude #-}++module Data.Digit.Class.LowerCase (++ -- * Classes+ Da(..)+ , Db(..)+ , Dc(..)+ , Dd(..)+ , De(..)+ , Df(..)++ -- * Parsers+ , parsea+ , parseb+ , parsec+ , parsed+ , parsee+ , parsef++) where++import Control.Category (id)+import Control.Lens (Prism', ( # ))++import Data.Functor ((<$))++import Text.Parser.Char (CharParsing, char)+import Text.Parser.Combinators ((<?>))++-- $setup+-- >>> import Data.Digit+-- >>> import Text.Parsec(parse, ParseError, eof)+-- >>> import Data.Void(Void)++class Da d where+ da ::+ Prism'+ d+ ()+ xa ::+ d+ xa =+ da # ()++instance Da () where+ da =+ id++class Db d where+ db ::+ Prism'+ d+ ()+ xb ::+ d+ xb =+ db # ()++instance Db () where+ db =+ id++class Dc d where+ dc ::+ Prism'+ d+ ()+ xc ::+ d+ xc =+ dc # ()++instance Dc () where+ dc =+ id++class Dd d where+ dd ::+ Prism'+ d+ ()+ xd ::+ d+ xd =+ dd # ()++instance Dd () where+ dd =+ id++class De d where+ de ::+ Prism'+ d+ ()+ xe ::+ d+ xe =+ de # ()++instance De () where+ de =+ id++class Df d where+ df ::+ Prism'+ d+ ()+ xf ::+ d+ xf =+ df # ()++instance Df () where+ df =+ id++-- |+--+-- >>> parse (parsea <* eof) "test" "a" :: Either ParseError HexDigit+-- Right HexDigita+--+-- >>> parse parsea "test" "axyz" :: Either ParseError HexDigit+-- Right HexDigita+--+-- >>> isn't _Right (parse parsea "test" "xyz" :: Either ParseError HexDigit)+-- True+parsea ::+ (Da d, CharParsing p) =>+ p d+parsea =+ xa <$ char 'a' <?> "a"++-- |+--+-- >>> parse (parseb <* eof) "test" "b" :: Either ParseError HexDigit+-- Right HexDigitb+--+-- >>> parse parseb "test" "bxyz" :: Either ParseError HexDigit+-- Right HexDigitb+--+-- >>> isn't _Right (parse parseb "test" "xyz" :: Either ParseError HexDigit)+-- True+parseb ::+ (Db d, CharParsing p) =>+ p d+parseb =+ xb <$ char 'b' <?> "b"++-- |+--+-- >>> parse (parsec <* eof) "test" "c" :: Either ParseError HexDigit+-- Right HexDigitc+--+-- >>> parse parsec "test" "cxyz" :: Either ParseError HexDigit+-- Right HexDigitc+--+-- >>> isn't _Right (parse parsec "test" "xyz" :: Either ParseError HexDigit)+-- True+parsec ::+ (Dc d, CharParsing p) =>+ p d+parsec =+ xc <$ char 'c' <?> "c"++-- |+--+-- >>> parse (parsed <* eof) "test" "d" :: Either ParseError HexDigit+-- Right HexDigitd+--+-- >>> parse parsed "test" "dxyz" :: Either ParseError HexDigit+-- Right HexDigitd+--+-- >>> isn't _Right (parse parsed "test" "xyz" :: Either ParseError HexDigit)+-- True+parsed ::+ (Dd d, CharParsing p) =>+ p d+parsed =+ xd <$ char 'd' <?> "d"++-- |+--+-- >>> parse (parsee <* eof) "test" "e" :: Either ParseError HexDigit+-- Right HexDigite+--+-- >>> parse parsee "test" "exyz" :: Either ParseError HexDigit+-- Right HexDigite+--+-- >>> isn't _Right (parse parsee "test" "xyz" :: Either ParseError HexDigit)+-- True+parsee ::+ (De d, CharParsing p) =>+ p d+parsee =+ xe <$ char 'e' <?> "e"++-- |+--+-- >>> parse (parsef <* eof) "test" "f" :: Either ParseError HexDigit+-- Right HexDigitf+--+-- >>> parse parsef "test" "fxyz" :: Either ParseError HexDigit+-- Right HexDigitf+--+-- >>> isn't _Right (parse parsef "test" "xyz" :: Either ParseError HexDigit)+-- True+parsef ::+ (Df d, CharParsing p) =>+ p d+parsef =+ xf <$ char 'f' <?> "f"
+ src/Data/Digit/Class/MixedCase.hs view
@@ -0,0 +1,192 @@+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE NoImplicitPrelude #-}+{-# LANGUAGE TypeFamilies #-}++module Data.Digit.Class.MixedCase+ (+ -- * Types+ DAa+ , DBb+ , DCc+ , DDd+ , DEe+ , DFf++ -- * Parsers+ , parseAa+ , parseBb+ , parseCc+ , parseDd+ , parseEe+ , parseFf++ -- * Re-exports+ , module Data.Digit.Class.UpperCase+ , module Data.Digit.Class.LowerCase++ ) where++import Text.Parser.Char (CharParsing)+import Text.Parser.Combinators (choice, (<?>))++import Data.Digit.Class.LowerCase+import Data.Digit.Class.UpperCase++-- $setup+-- >>> import Text.Parsec(parse, ParseError, eof)+-- >>> import Data.Void(Void)+-- >>> import Data.Digit+-- >>> import Papa++type DAa a =+ (DA a, Da a)++type DBb a =+ (DB a, Db a)++type DCc a =+ (DC a, Dc a)++type DDd a =+ (DD a, Dd a)++type DEe a =+ (DE a, De a)++type DFf a =+ (DF a, Df a)++-- |+--+-- >>> parse (parseAa <* eof) "test" "A" :: Either ParseError HeXDigit+-- Right HeXDigitA+--+-- >>> parse parseAa "test" "Axyz" :: Either ParseError HeXDigit+-- Right HeXDigitA+--+-- >>> parse (parseAa <* eof) "test" "a" :: Either ParseError HeXDigit+-- Right HeXDigita+--+-- >>> parse parseAa "test" "axyz" :: Either ParseError HeXDigit+-- Right HeXDigita+--+-- >>> isn't _Right (parse parseAa "test" "xyz" :: Either ParseError HeXDigit)+-- True+parseAa ::+ (DAa d, CharParsing p) =>+ p d+parseAa =+ choice [parseA, parsea] <?> "Aa"++-- |+--+-- >>> parse (parseBb <* eof) "test" "B" :: Either ParseError HeXDigit+-- Right HeXDigitB+--+-- >>> parse parseBb "test" "Bxyz" :: Either ParseError HeXDigit+-- Right HeXDigitB+--+-- >>> parse (parseBb <* eof) "test" "b" :: Either ParseError HeXDigit+-- Right HeXDigitb+--+-- >>> parse parseBb "test" "bxyz" :: Either ParseError HeXDigit+-- Right HeXDigitb+--+-- >>> isn't _Right (parse parseBb "test" "xyz" :: Either ParseError HeXDigit)+-- True+parseBb ::+ (DBb d, CharParsing p) =>+ p d+parseBb =+ choice [parseB, parseb] <?> "Bb"++-- |+--+-- >>> parse (parseCc <* eof) "test" "C" :: Either ParseError HeXDigit+-- Right HeXDigitC+--+-- >>> parse parseCc "test" "Cxyz" :: Either ParseError HeXDigit+-- Right HeXDigitC+--+-- >>> parse (parseCc <* eof) "test" "c" :: Either ParseError HeXDigit+-- Right HeXDigitc+--+-- >>> parse parseCc "test" "cxyz" :: Either ParseError HeXDigit+-- Right HeXDigitc+--+-- >>> isn't _Right (parse parseCc "test" "xyz" :: Either ParseError HeXDigit)+-- True+parseCc ::+ (DCc d, CharParsing p) =>+ p d+parseCc =+ choice [parseC, parsec] <?> "Cc"+++-- |+--+-- >>> parse (parseDd <* eof) "test" "D" :: Either ParseError HeXDigit+-- Right HeXDigitD+--+-- >>> parse parseDd "test" "Dxyz" :: Either ParseError HeXDigit+-- Right HeXDigitD+--+-- >>> parse (parseDd <* eof) "test" "d" :: Either ParseError HeXDigit+-- Right HeXDigitd+--+-- >>> parse parseDd "test" "dxyz" :: Either ParseError HeXDigit+-- Right HeXDigitd+--+-- >>> isn't _Right (parse parseDd "test" "xyz" :: Either ParseError HeXDigit)+-- True+parseDd ::+ (DDd d, CharParsing p) =>+ p d+parseDd =+ choice [parseD, parsed] <?> "Dd"++-- |+--+-- >>> parse (parseEe <* eof) "test" "E" :: Either ParseError HeXDigit+-- Right HeXDigitE+--+-- >>> parse parseEe "test" "Exyz" :: Either ParseError HeXDigit+-- Right HeXDigitE+--+-- >>> parse (parseEe <* eof) "test" "e" :: Either ParseError HeXDigit+-- Right HeXDigite+--+-- >>> parse parseEe "test" "exyz" :: Either ParseError HeXDigit+-- Right HeXDigite+--+-- >>> isn't _Right (parse parseEe "test" "xyz" :: Either ParseError HeXDigit)+-- True+parseEe ::+ (DEe d, CharParsing p) =>+ p d+parseEe =+ choice [parseE, parsee] <?> "Ee"++-- |+--+-- >>> parse (parseFf <* eof) "test" "F" :: Either ParseError HeXDigit+-- Right HeXDigitF+--+-- >>> parse parseFf "test" "Fxyz" :: Either ParseError HeXDigit+-- Right HeXDigitF+--+-- >>> parse (parseFf <* eof) "test" "f" :: Either ParseError HeXDigit+-- Right HeXDigitf+--+-- >>> parse parseFf "test" "fxyz" :: Either ParseError HeXDigit+-- Right HeXDigitf+--+-- >>> isn't _Right (parse parseFf "test" "xyz" :: Either ParseError HeXDigit)+-- True+parseFf ::+ (DFf d, CharParsing p) =>+ p d+parseFf =+ choice [parseF, parsef] <?> "Ff"
+ src/Data/Digit/Class/UpperCase.hs view
@@ -0,0 +1,213 @@+{-# LANGUAGE NoImplicitPrelude #-}++module Data.Digit.Class.UpperCase+ (+ -- * Classes+ DA(..)+ , DB(..)+ , DC(..)+ , DD(..)+ , DE(..)+ , DF(..)++ -- * Parsers+ , parseA+ , parseB+ , parseC+ , parseD+ , parseE+ , parseF+ ) where++import Control.Category (id)+import Control.Lens (Prism', ( # ))++import Data.Functor ((<$))++import Text.Parser.Char (CharParsing, char)+import Text.Parser.Combinators ((<?>))++-- $setup+-- >>> import Data.Digit+-- >>> import Text.Parsec(parse, ParseError, eof)+-- >>> import Data.Void(Void)++class DA d where+ dA ::+ Prism'+ d+ ()+ xA ::+ d+ xA =+ dA # ()++instance DA () where+ dA =+ id++class DB d where+ dB ::+ Prism'+ d+ ()+ xB ::+ d+ xB =+ dB # ()++instance DB () where+ dB =+ id++class DC d where+ dC ::+ Prism'+ d+ ()+ xC ::+ d+ xC =+ dC # ()++instance DC () where+ dC =+ id++class DD d where+ dD ::+ Prism'+ d+ ()+ xD ::+ d+ xD =+ dD # ()++instance DD () where+ dD =+ id++class DE d where+ dE ::+ Prism'+ d+ ()+ xE ::+ d+ xE =+ dE # ()++instance DE () where+ dE =+ id++class DF d where+ dF ::+ Prism'+ d+ ()+ xF ::+ d+ xF =+ dF # ()++instance DF () where+ dF =+ id++-- |+--+-- >>> parse (parseA <* eof) "test" "A" :: Either ParseError HEXDigit+-- Right HEXDigitA+--+-- >>> parse parseA "test" "Axyz" :: Either ParseError HEXDigit+-- Right HEXDigitA+--+-- >>> isn't _Right (parse parseA "test" "xyz" :: Either ParseError HEXDigit)+-- True+parseA ::+ (DA d, CharParsing p) =>+ p d+parseA =+ xA <$ char 'A' <?> "A"++-- |+--+-- >>> parse (parseB <* eof) "test" "B" :: Either ParseError HEXDigit+-- Right HEXDigitB+--+-- >>> parse parseB "test" "Bxyz" :: Either ParseError HEXDigit+-- Right HEXDigitB+--+-- >>> isn't _Right (parse parseB "test" "xyz" :: Either ParseError HEXDigit)+-- True+parseB ::+ (DB d, CharParsing p) =>+ p d+parseB =+ xB <$ char 'B' <?> "B"++-- |+--+-- >>> parse (parseC <* eof) "test" "C" :: Either ParseError HEXDigit+-- Right HEXDigitC+--+-- >>> parse parseC "test" "Cxyz" :: Either ParseError HEXDigit+-- Right HEXDigitC+--+-- >>> isn't _Right (parse parseC "test" "xyz" :: Either ParseError HEXDigit)+-- True+parseC ::+ (DC d, CharParsing p) =>+ p d+parseC =+ xC <$ char 'C' <?> "C"++-- |+--+-- >>> parse (parseD <* eof) "test" "D" :: Either ParseError HEXDigit+-- Right HEXDigitD+--+-- >>> parse parseD "test" "Dxyz" :: Either ParseError HEXDigit+-- Right HEXDigitD+--+-- >>> isn't _Right (parse parseD "test" "xyz" :: Either ParseError HEXDigit)+-- True+parseD ::+ (DD d, CharParsing p) =>+ p d+parseD =+ xD <$ char 'D' <?> "D"++-- |+--+-- >>> parse (parseE <* eof) "test" "E" :: Either ParseError HEXDigit+-- Right HEXDigitE+--+-- >>> parse parseE "test" "Exyz" :: Either ParseError HEXDigit+-- Right HEXDigitE+--+-- >>> isn't _Right (parse parseE "test" "xyz" :: Either ParseError HEXDigit)+-- True+parseE ::+ (DE d, CharParsing p) =>+ p d+parseE =+ xE <$ char 'E' <?> "E"++-- |+--+-- >>> parse (parseF <* eof) "test" "F" :: Either ParseError HEXDigit+-- Right HEXDigitF+--+-- >>> parse parseF "test" "Fxyz" :: Either ParseError HEXDigit+-- Right HEXDigitF+--+-- >>> isn't _Right (parse parseF "test" "xyz" :: Either ParseError HEXDigit)+-- True+parseF ::+ (DF d, CharParsing p) =>+ p d+parseF =+ xF <$ char 'F' <?> "F"
− src/Data/Digit/D0.hs
@@ -1,9 +0,0 @@-{-# LANGUAGE NoImplicitPrelude #-}--module Data.Digit.D0 where--import Prelude(Eq)--class Eq a => D0 a where- d0 ::- a
− src/Data/Digit/D1.hs
@@ -1,9 +0,0 @@-{-# LANGUAGE NoImplicitPrelude #-}--module Data.Digit.D1 where--import Prelude(Eq)--class Eq a => D1 a where- d1 ::- a
− src/Data/Digit/D2.hs
@@ -1,9 +0,0 @@-{-# LANGUAGE NoImplicitPrelude #-}--module Data.Digit.D2 where--import Prelude(Eq)--class Eq a => D2 a where- d2 ::- a
− src/Data/Digit/D3.hs
@@ -1,9 +0,0 @@-{-# LANGUAGE NoImplicitPrelude #-}--module Data.Digit.D3 where--import Prelude(Eq)--class Eq a => D3 a where- d3 ::- a
− src/Data/Digit/D4.hs
@@ -1,9 +0,0 @@-{-# LANGUAGE NoImplicitPrelude #-}--module Data.Digit.D4 where--import Prelude(Eq)--class Eq a => D4 a where- d4 ::- a
− src/Data/Digit/D5.hs
@@ -1,9 +0,0 @@-{-# LANGUAGE NoImplicitPrelude #-}--module Data.Digit.D5 where--import Prelude(Eq)--class Eq a => D5 a where- d5 ::- a
− src/Data/Digit/D6.hs
@@ -1,9 +0,0 @@-{-# LANGUAGE NoImplicitPrelude #-}--module Data.Digit.D6 where--import Prelude(Eq)--class Eq a => D6 a where- d6 ::- a
− src/Data/Digit/D7.hs
@@ -1,9 +0,0 @@-{-# LANGUAGE NoImplicitPrelude #-}--module Data.Digit.D7 where--import Prelude(Eq)--class Eq a => D7 a where- d7 ::- a
− src/Data/Digit/D8.hs
@@ -1,9 +0,0 @@-{-# LANGUAGE NoImplicitPrelude #-}--module Data.Digit.D8 where--import Prelude(Eq)--class Eq a => D8 a where- d8 ::- a
− src/Data/Digit/D9.hs
@@ -1,9 +0,0 @@-{-# LANGUAGE NoImplicitPrelude #-}--module Data.Digit.D9 where--import Prelude(Eq)--class Eq a => D9 a where- d9 ::- a
+ src/Data/Digit/Decimal.hs view
@@ -0,0 +1,133 @@+{-# LANGUAGE NoImplicitPrelude #-}+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE TemplateHaskell #-}++module Data.Digit.Decimal(+ DecDigit(..)+, DecDigitNoZero(..)+, DecimalNoZero+, Decimal+, parseDecimalNoZero+, parseDecimal+-- * Prisms+, _DecDigit0+, _DecDigit1+, _DecDigit2+, _DecDigit3+, _DecDigit4+, _DecDigit5+, _DecDigit6+, _DecDigit7+, _DecDigit8+, _DecDigit9+-- * Re-exports+, module Data.Digit.Class.D0+, module Data.Digit.Class.D1+, module Data.Digit.Class.D2+, module Data.Digit.Class.D3+, module Data.Digit.Class.D4+, module Data.Digit.Class.D5+, module Data.Digit.Class.D6+, module Data.Digit.Class.D7+, module Data.Digit.Class.D8+, module Data.Digit.Class.D9+) where++import Prelude (Eq, Show, Ord, Enum, Bounded)+import Control.Lens.TH (makePrisms)+import Text.Parser.Char(CharParsing)+import Text.Parser.Combinators((<?>), choice)++import Data.Digit.Class.D0+import Data.Digit.Class.D1+import Data.Digit.Class.D2+import Data.Digit.Class.D3+import Data.Digit.Class.D4+import Data.Digit.Class.D5+import Data.Digit.Class.D6+import Data.Digit.Class.D7+import Data.Digit.Class.D8+import Data.Digit.Class.D9++data DecDigit+ = DecDigit0+ | DecDigit1+ | DecDigit2+ | DecDigit3+ | DecDigit4+ | DecDigit5+ | DecDigit6+ | DecDigit7+ | DecDigit8+ | DecDigit9+ deriving (Show, Eq, Ord, Enum, Bounded)++makePrisms ''DecDigit++instance D0 DecDigit where; d0 = _DecDigit0+instance D1 DecDigit where; d1 = _DecDigit1+instance D2 DecDigit where; d2 = _DecDigit2+instance D3 DecDigit where; d3 = _DecDigit3+instance D4 DecDigit where; d4 = _DecDigit4+instance D5 DecDigit where; d5 = _DecDigit5+instance D6 DecDigit where; d6 = _DecDigit6+instance D7 DecDigit where; d7 = _DecDigit7+instance D8 DecDigit where; d8 = _DecDigit8+instance D9 DecDigit where; d9 = _DecDigit9++data DecDigitNoZero =+ DecDigitNoZero1+ | DecDigitNoZero2+ | DecDigitNoZero3+ | DecDigitNoZero4+ | DecDigitNoZero5+ | DecDigitNoZero6+ | DecDigitNoZero7+ | DecDigitNoZero8+ | DecDigitNoZero9+ deriving (Show, Eq, Ord, Enum, Bounded)++makePrisms ''DecDigitNoZero++instance D1 DecDigitNoZero where; d1 = _DecDigitNoZero1+instance D2 DecDigitNoZero where; d2 = _DecDigitNoZero2+instance D3 DecDigitNoZero where; d3 = _DecDigitNoZero3+instance D4 DecDigitNoZero where; d4 = _DecDigitNoZero4+instance D5 DecDigitNoZero where; d5 = _DecDigitNoZero5+instance D6 DecDigitNoZero where; d6 = _DecDigitNoZero6+instance D7 DecDigitNoZero where; d7 = _DecDigitNoZero7+instance D8 DecDigitNoZero where; d8 = _DecDigitNoZero8+instance D9 DecDigitNoZero where; d9 = _DecDigitNoZero9++type DecimalNoZero d =+ (D1 d, D2 d, D3 d, D4 d, D5 d, D6 d, D7 d, D8 d, D9 d)++parseDecimalNoZero ::+ (DecimalNoZero d, CharParsing p) =>+ p d+parseDecimalNoZero =+ choice+ [+ parse1+ , parse2+ , parse3+ , parse4+ , parse5+ , parse6+ , parse7+ , parse8+ , parse9+ ] <?> "DecimalNoZero"++type Decimal d =+ (D0 d, DecimalNoZero d)++parseDecimal ::+ (Decimal d, CharParsing p) =>+ p d+parseDecimal =+ choice+ [+ parse0+ , parseDecimalNoZero+ ] <?> "Decimal"
− src/Data/Digit/Digit.hs
@@ -1,272 +0,0 @@-{-# LANGUAGE NoImplicitPrelude, DeriveDataTypeable, TemplateHaskell, QuasiQuotes #-}---- | A data type with ten nullary constructors [0-9] and combinators.-module Data.Digit.Digit-(--- * Data type- Digit--- * Destructors-, foldDigit--- * Prisms-, digit-, digitC-, digitQ-) where--import Prelude(Show(..), Read(..), Eq, Enum(..), Maybe(..), Bounded, Ord, Int, Char, (.), const, maybe, error)-import Data.Digit.D0-import Data.Digit.D1-import Data.Digit.D2-import Data.Digit.D3-import Data.Digit.D4-import Data.Digit.D5-import Data.Digit.D6-import Data.Digit.D7-import Data.Digit.D8-import Data.Digit.D9-import Control.Lens-import Data.Data (Data)-import Data.Typeable (Typeable)-import Language.Haskell.TH-import Language.Haskell.TH.Quote---- $setup--- >>> import Prelude---- | A data type with ten nullary constructors.-data Digit =- D0- | D1- | D2- | D3- | D4- | D5- | D6- | D7- | D8- | D9- deriving (Eq, Ord, Enum, Bounded, Data, Typeable)---- | Catamorphism for @Digit@.------ prop> foldDigit x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 d0 == x0------ prop> foldDigit x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 d1 == x1------ prop> foldDigit x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 d2 == x2------ prop> foldDigit x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 d3 == x3------ prop> foldDigit x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 d4 == x4------ prop> foldDigit x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 d5 == x5------ prop> foldDigit x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 d6 == x6------ prop> foldDigit x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 d7 == x7------ prop> foldDigit x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 d8 == x8------ prop> foldDigit x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 d9 == x9-foldDigit ::- a -- ^ Zero.- -> a -- ^ One.- -> a -- ^ Two.- -> a -- ^ Three.- -> a -- ^ Four.- -> a -- ^ Five.- -> a -- ^ Six.- -> a -- ^ Seven.- -> a -- ^ Eight.- -> a -- ^ Nine.- -> Digit -- ^ The digit to fold.- -> a-foldDigit x0 _ _ _ _ _ _ _ _ _ D0 =- x0-foldDigit _ x1 _ _ _ _ _ _ _ _ D1 =- x1-foldDigit _ _ x2 _ _ _ _ _ _ _ D2 =- x2-foldDigit _ _ _ x3 _ _ _ _ _ _ D3 =- x3-foldDigit _ _ _ _ x4 _ _ _ _ _ D4 =- x4-foldDigit _ _ _ _ _ x5 _ _ _ _ D5 =- x5-foldDigit _ _ _ _ _ _ x6 _ _ _ D6 =- x6-foldDigit _ _ _ _ _ _ _ x7 _ _ D7 =- x7-foldDigit _ _ _ _ _ _ _ _ x8 _ D8 =- x8-foldDigit _ _ _ _ _ _ _ _ _ x9 D9 =- x9--instance D0 Digit where- d0 =- D0--instance D1 Digit where- d1 =- D1--instance D2 Digit where- d2 =- D2--instance D3 Digit where- d3 =- D3--instance D4 Digit where- d4 =- D4--instance D5 Digit where- d5 =- D5--instance D6 Digit where- d6 =- D6--instance D7 Digit where- d7 =- D7--instance D8 Digit where- d8 =- D8--instance D9 Digit where- d9 =- D9---- | A prism for using @Int@ as @Digit@.------ >>> 5 ^? digit--- Just 5------ >>> 0 ^? digit--- Just 0------ >>> 9 ^? digit--- Just 9------ >>> 10 ^? digit--- Nothing------ >>> (-5) ^? digit--- Nothing-digit ::- Prism' Int Digit-digit =- prism'- fromEnum- (\n -> case n of 0 -> Just D0- 1 -> Just D1- 2 -> Just D2- 3 -> Just D3- 4 -> Just D4- 5 -> Just D5- 6 -> Just D6- 7 -> Just D7- 8 -> Just D8- 9 -> Just D9- _ -> Nothing)---- | A prism for using @Char@ as @Digit@.------ >>> '5' ^? digitC--- Just 5------ >>> '0' ^? digitC--- Just 0------ >>> '9' ^? digitC--- Just 9------ >>> 'a' ^? digitC--- Nothing------ >>> '@' ^? digitC--- Nothing-digitC ::- Prism' Char Digit-digitC =- prism'- (\d -> case d of D0 -> '0'- D1 -> '1'- D2 -> '2'- D3 -> '3'- D4 -> '4'- D5 -> '5'- D6 -> '6'- D7 -> '7'- D8 -> '8'- D9 -> '9')- (\n -> case n of '0' -> Just D0- '1' -> Just D1- '2' -> Just D2- '3' -> Just D3- '4' -> Just D4- '5' -> Just D5- '6' -> Just D6- '7' -> Just D7- '8' -> Just D8- '9' -> Just D9- _ -> Nothing)--instance Show Digit where- show = show . fromEnum--instance Read Digit where- readsPrec _ ('0':t) =- [(D0, t)]- readsPrec _ ('1':t) =- [(D1, t)]- readsPrec _ ('2':t) =- [(D2, t)]- readsPrec _ ('3':t) =- [(D3, t)]- readsPrec _ ('4':t) =- [(D4, t)]- readsPrec _ ('5':t) =- [(D5, t)]- readsPrec _ ('6':t) =- [(D6, t)]- readsPrec _ ('7':t) =- [(D7, t)]- readsPrec _ ('8':t) =- [(D8, t)]- readsPrec _ ('9':t) =- [(D9, t)]- readsPrec _ _ =- []---- | A QuasiQuoter for any range of @Digit@.------ [digitQ|4|] :: Digit--- 4------ named [digitQ|4|] = "four"--- named [digitQ|$x|] = "not four, " ++ show x ++ " instead"------ mod10D x = let y = mod x 10 in [digitQ|$y|]-digitQ :: QuasiQuoter-digitQ = QuasiQuoter {- quoteExp = dexp- , quotePat = dpat- , quoteType = error "not quotable"- , quoteDec = error "not quotable"- }--dexp :: [Char] -> ExpQ-dexp ('$':vn) = varE (mkName vn)-dexp (d:[]) = maybe (error "not a digit") (dataToExpQ (const Nothing)) (d ^? digitC)-dexp _ = error "not a digit"--dpat :: [Char] -> PatQ-dpat ('$':vn) = varP (mkName vn)-dpat (d:[]) = maybe (error "not a digit") (dataToPatQ (const Nothing)) (d ^? digitC)-dpat _ = error "not a digit"
− src/Data/Digit/Digit1_8.hs
@@ -1,255 +0,0 @@-{-# LANGUAGE NoImplicitPrelude, DeriveDataTypeable #-}---- | A data type with eight nullary constructors [1-8] and combinators.-module Data.Digit.Digit1_8-(--- * Data type- Digit1_8--- * Destructors-, foldDigit1_8--- * Prisms-, digit1_8-, digitC1_8-, digit1_8digit-, digit1_8digit1_9-) where--import Prelude(Show(..), Read(..), Eq, Enum(..), Maybe(..), Bounded, Ord, Int, Char, (.))-import Data.Digit.Digit(Digit, digit, digitC)-import Data.Digit.Digit1_9(Digit1_9, foldDigit1_9, digit1_9digit)-import Data.Digit.D1-import Data.Digit.D2-import Data.Digit.D3-import Data.Digit.D4-import Data.Digit.D5-import Data.Digit.D6-import Data.Digit.D7-import Data.Digit.D8-import Control.Lens-import Data.Data (Data)-import Data.Typeable (Typeable)---- $setup--- >>> import Prelude--- >>> import Data.Digit.D0--- >>> import Data.Digit.D9---- | A data type with eight nullary constructors.-data Digit1_8 =- D1- | D2- | D3- | D4- | D5- | D6- | D7- | D8- deriving (Eq, Ord, Enum, Bounded, Data, Typeable)---- | Catamorphism for @Digit1_8@.------ prop> foldDigit1_8 x1 x2 x3 x4 x5 x6 x7 x8 d1 == x1------ prop> foldDigit1_8 x1 x2 x3 x4 x5 x6 x7 x8 d2 == x2------ prop> foldDigit1_8 x1 x2 x3 x4 x5 x6 x7 x8 d3 == x3------ prop> foldDigit1_8 x1 x2 x3 x4 x5 x6 x7 x8 d4 == x4------ prop> foldDigit1_8 x1 x2 x3 x4 x5 x6 x7 x8 d5 == x5------ prop> foldDigit1_8 x1 x2 x3 x4 x5 x6 x7 x8 d6 == x6------ prop> foldDigit1_8 x1 x2 x3 x4 x5 x6 x7 x8 d7 == x7------ prop> foldDigit1_8 x1 x2 x3 x4 x5 x6 x7 x8 d8 == x8-foldDigit1_8 ::- a -- ^ One.- -> a -- ^ Two.- -> a -- ^ Three.- -> a -- ^ Four.- -> a -- ^ Five.- -> a -- ^ Six.- -> a -- ^ Seven.- -> a -- ^ Eight.- -> Digit1_8 -- ^ The digit to fold.- -> a-foldDigit1_8 x1 _ _ _ _ _ _ _ D1 =- x1-foldDigit1_8 _ x2 _ _ _ _ _ _ D2 =- x2-foldDigit1_8 _ _ x3 _ _ _ _ _ D3 =- x3-foldDigit1_8 _ _ _ x4 _ _ _ _ D4 =- x4-foldDigit1_8 _ _ _ _ x5 _ _ _ D5 =- x5-foldDigit1_8 _ _ _ _ _ x6 _ _ D6 =- x6-foldDigit1_8 _ _ _ _ _ _ x7 _ D7 =- x7-foldDigit1_8 _ _ _ _ _ _ _ x8 D8 =- x8--instance D1 Digit1_8 where- d1 =- D1--instance D2 Digit1_8 where- d2 =- D2--instance D3 Digit1_8 where- d3 =- D3--instance D4 Digit1_8 where- d4 =- D4--instance D5 Digit1_8 where- d5 =- D5--instance D6 Digit1_8 where- d6 =- D6--instance D7 Digit1_8 where- d7 =- D7--instance D8 Digit1_8 where- d8 =- D8---- | A prism for using @Int@ as @Digit1_8@.------ >>> 5 ^? digit1_8--- Just 5------ >>> 0 ^? digit1_8--- Nothing------ >>> 8 ^? digit1_8--- Just 8------ >>> 9 ^? digit1_8--- Nothing------ >>> 10 ^? digit1_8--- Nothing------ >>> (-5) ^? digit1_8--- Nothing-digit1_8 ::- Prism' Int Digit1_8-digit1_8 =- digit . digit1_8digit---- | A prism for using @Char@ as @Digit1_8@.------ >>> '5' ^? digitC1_8--- Just 5------ >>> '0' ^? digitC1_8--- Nothing------ >>> '8' ^? digitC1_8--- Just 8------ >>> '9' ^? digitC1_8--- Nothing------ >>> 'x' ^? digitC1_8--- Nothing------ >>> '*' ^? digitC1_8--- Nothing-digitC1_8 ::- Prism' Char Digit1_8-digitC1_8 =- digitC . digit1_8digit---- | A prism for using @Digit@ as @Digit1_8@.------ >>> d5 ^? digit1_8digit--- Just 5------ >>> d0 ^? digit1_8digit--- Nothing------ >>> d8 ^? digit1_8digit--- Just 8------ >>> d9 ^? digit1_8digit--- Nothing------ >>> d1 ^? digit1_8digit--- Just 1-digit1_8digit ::- Prism' Digit Digit1_8-digit1_8digit =- digit1_9digit . digit1_8digit1_9---- | A prism for using @Digit1_9@ as @Digit1_8@.------ >>> d5 ^? digit1_8digit1_9--- Just 5------ >>> d8 ^? digit1_8digit1_9--- Just 8------ >>> d9 ^? digit1_8digit1_9--- Nothing------ >>> d1 ^? digit1_8digit1_9--- Just 1-digit1_8digit1_9 ::- Prism' Digit1_9 Digit1_8-digit1_8digit1_9 =- prism'- (foldDigit1_8- d1- d2- d3- d4- d5- d6- d7- d8)- (foldDigit1_9- (Just D1)- (Just D2)- (Just D3)- (Just D4)- (Just D5)- (Just D6)- (Just D7)- (Just D8)- Nothing)---instance Show Digit1_8 where- show d =- show (digit1_8 # d)--instance Read Digit1_8 where- readsPrec _ ('1':t) =- [(D1, t)]- readsPrec _ ('2':t) =- [(D2, t)]- readsPrec _ ('3':t) =- [(D3, t)]- readsPrec _ ('4':t) =- [(D4, t)]- readsPrec _ ('5':t) =- [(D5, t)]- readsPrec _ ('6':t) =- [(D6, t)]- readsPrec _ ('7':t) =- [(D7, t)]- readsPrec _ ('8':t) =- [(D8, t)]- readsPrec _ _ =- []
− src/Data/Digit/Digit1_9.hs
@@ -1,239 +0,0 @@-{-# LANGUAGE NoImplicitPrelude, DeriveDataTypeable #-}---- | A data type with nine nullary constructors [1-9] and combinators.-module Data.Digit.Digit1_9-(--- * Data type- Digit1_9--- * Destructors-, foldDigit1_9--- * Prisms-, digit1_9-, digitC1_9-, digit1_9digit-) where--import Prelude(Show(..), Read(..), Eq, Enum(..), Maybe(..), Bounded, Ord, Int, Char, (.))-import Data.Digit.Digit(Digit, foldDigit, digit, digitC)-import Data.Digit.D1-import Data.Digit.D2-import Data.Digit.D3-import Data.Digit.D4-import Data.Digit.D5-import Data.Digit.D6-import Data.Digit.D7-import Data.Digit.D8-import Data.Digit.D9-import Control.Lens-import Data.Data (Data)-import Data.Typeable (Typeable)---- $setup--- >>> import Prelude--- >>> import Data.Digit.D0---- | A data type with nine nullary constructors.-data Digit1_9 =- D1- | D2- | D3- | D4- | D5- | D6- | D7- | D8- | D9- deriving (Eq, Ord, Enum, Bounded, Data, Typeable)---- | Catamorphism for @Digit1_9@.------ prop> foldDigit1_9 x1 x2 x3 x4 x5 x6 x7 x8 x9 d1 == x1------ prop> foldDigit1_9 x1 x2 x3 x4 x5 x6 x7 x8 x9 d2 == x2------ prop> foldDigit1_9 x1 x2 x3 x4 x5 x6 x7 x8 x9 d3 == x3------ prop> foldDigit1_9 x1 x2 x3 x4 x5 x6 x7 x8 x9 d4 == x4------ prop> foldDigit1_9 x1 x2 x3 x4 x5 x6 x7 x8 x9 d5 == x5------ prop> foldDigit1_9 x1 x2 x3 x4 x5 x6 x7 x8 x9 d6 == x6------ prop> foldDigit1_9 x1 x2 x3 x4 x5 x6 x7 x8 x9 d7 == x7------ prop> foldDigit1_9 x1 x2 x3 x4 x5 x6 x7 x8 x9 d8 == x8------ prop> foldDigit1_9 x1 x2 x3 x4 x5 x6 x7 x8 x9 d9 == x9-foldDigit1_9 ::- a -- ^ One.- -> a -- ^ Two.- -> a -- ^ Three.- -> a -- ^ Four.- -> a -- ^ Five.- -> a -- ^ Six.- -> a -- ^ Seven.- -> a -- ^ Eight.- -> a -- ^ Nine.- -> Digit1_9 -- ^ The digit to fold.- -> a-foldDigit1_9 x1 _ _ _ _ _ _ _ _ D1 =- x1-foldDigit1_9 _ x2 _ _ _ _ _ _ _ D2 =- x2-foldDigit1_9 _ _ x3 _ _ _ _ _ _ D3 =- x3-foldDigit1_9 _ _ _ x4 _ _ _ _ _ D4 =- x4-foldDigit1_9 _ _ _ _ x5 _ _ _ _ D5 =- x5-foldDigit1_9 _ _ _ _ _ x6 _ _ _ D6 =- x6-foldDigit1_9 _ _ _ _ _ _ x7 _ _ D7 =- x7-foldDigit1_9 _ _ _ _ _ _ _ x8 _ D8 =- x8-foldDigit1_9 _ _ _ _ _ _ _ _ x9 D9 =- x9--instance D1 Digit1_9 where- d1 =- D1--instance D2 Digit1_9 where- d2 =- D2--instance D3 Digit1_9 where- d3 =- D3--instance D4 Digit1_9 where- d4 =- D4--instance D5 Digit1_9 where- d5 =- D5--instance D6 Digit1_9 where- d6 =- D6--instance D7 Digit1_9 where- d7 =- D7--instance D8 Digit1_9 where- d8 =- D8--instance D9 Digit1_9 where- d9 =- D9---- | A prism for using @Int@ as @Digit1_9@.------ >>> 5 ^? digit1_9--- Just 5------ >>> 0 ^? digit1_9--- Nothing------ >>> 9 ^? digit1_9--- Just 9------ >>> 10 ^? digit1_9--- Nothing------ >>> (-5) ^? digit1_9--- Nothing-digit1_9 ::- Prism' Int Digit1_9-digit1_9 =- digit . digit1_9digit---- | A prism for using @Char@ as @Digit1_9@.------ >>> '5' ^? digitC1_9--- Just 5------ >>> '0' ^? digitC1_9--- Nothing------ >>> '9' ^? digitC1_9--- Just 9------ >>> 'x' ^? digitC1_9--- Nothing------ >>> '*' ^? digitC1_9--- Nothing-digitC1_9 ::- Prism' Char Digit1_9-digitC1_9 =- digitC . digit1_9digit---- | A prism for using @Digit@ as @Digit1_9@.------ >>> d5 ^? digit1_9digit--- Just 5------ >>> d0 ^? digit1_9digit--- Nothing------ >>> d9 ^? digit1_9digit--- Just 9------ >>> d1 ^? digit1_9digit--- Just 1-digit1_9digit ::- Prism' Digit Digit1_9-digit1_9digit =- prism'- (foldDigit1_9- d1- d2- d3- d4- d5- d6- d7- d8- d9)- (foldDigit- Nothing- (Just D1)- (Just D2)- (Just D3)- (Just D4)- (Just D5)- (Just D6)- (Just D7)- (Just D8)- (Just D9))--instance Show Digit1_9 where- show d =- show (digit1_9 # d)--instance Read Digit1_9 where- readsPrec _ ('1':t) =- [(D1, t)]- readsPrec _ ('2':t) =- [(D2, t)]- readsPrec _ ('3':t) =- [(D3, t)]- readsPrec _ ('4':t) =- [(D4, t)]- readsPrec _ ('5':t) =- [(D5, t)]- readsPrec _ ('6':t) =- [(D6, t)]- readsPrec _ ('7':t) =- [(D7, t)]- readsPrec _ ('8':t) =- [(D8, t)]- readsPrec _ ('9':t) =- [(D9, t)]- readsPrec _ _ =- []
+ src/Data/Digit/Enum.hs view
@@ -0,0 +1,169 @@+module Data.Digit.Enum+ ( -- * Binary+ enumBinaryNoZero+ , enumBinary+ -- * Octal+ , enumOctalNoZero+ , enumOctal+ -- * Decimal+ , enumDecimalNoZero+ , enumDecimal+ -- * Hexadecimal+ , enumHexadecimalNoZero+ , enumHexadecimal+ -- * HEXADECIMAL+ , enumHEXADECIMALNoZero+ , enumHEXADECIMAL+ )+where++import Control.Lens.Review ((#))+import Data.Digit.Binary+import Data.Digit.Decimal+import Data.Digit.Hexadecimal.LowerCase+import Data.Digit.Hexadecimal.UpperCase+import Data.Digit.Octal++-- | @[1]@+enumBinaryNoZero :: BinaryNoZero d => [d]+enumBinaryNoZero = [d1 # ()]++-- | @[0, 1]@+enumBinary :: Binary d => [d]+enumBinary = [d0 # (), d1 # ()]++-- | @[1..7]@+enumOctalNoZero :: OctalNoZero d => [d]+enumOctalNoZero =+ [ d1 # ()+ , d2 # ()+ , d3 # ()+ , d4 # ()+ , d5 # ()+ , d6 # ()+ , d7 # ()+ ]++-- | @[0..7]@+enumOctal :: Octal d => [d]+enumOctal =+ [ d0 # ()+ , d1 # ()+ , d2 # ()+ , d3 # ()+ , d4 # ()+ , d5 # ()+ , d6 # ()+ , d7 # ()+ ]++-- | @[1..9]@+enumDecimalNoZero :: DecimalNoZero d => [d]+enumDecimalNoZero =+ [ d1 # ()+ , d2 # ()+ , d3 # ()+ , d4 # ()+ , d5 # ()+ , d6 # ()+ , d7 # ()+ , d8 # ()+ , d9 # ()+ ]++-- | @[0..9]@+enumDecimal :: Decimal d => [d]+enumDecimal =+ [ d0 # ()+ , d1 # ()+ , d2 # ()+ , d3 # ()+ , d4 # ()+ , d5 # ()+ , d6 # ()+ , d7 # ()+ , d8 # ()+ , d9 # ()+ ]++-- | @[1..9] ++ [a..f]@+enumHexadecimalNoZero :: HexadecimalNoZero d => [d]+enumHexadecimalNoZero =+ [ d1 # ()+ , d2 # ()+ , d3 # ()+ , d4 # ()+ , d5 # ()+ , d6 # ()+ , d7 # ()+ , d8 # ()+ , d9 # ()+ , da # ()+ , db # ()+ , dc # ()+ , dd # ()+ , de # ()+ , df # ()+ ]++-- | @[0..9] ++ [a..f]@+enumHexadecimal :: Hexadecimal d => [d]+enumHexadecimal =+ [ d0 # ()+ , d1 # ()+ , d2 # ()+ , d3 # ()+ , d4 # ()+ , d5 # ()+ , d6 # ()+ , d7 # ()+ , d8 # ()+ , d9 # ()+ , da # ()+ , db # ()+ , dc # ()+ , dd # ()+ , de # ()+ , df # ()+ ]++-- | @[1..9] ++ [A..F]@+enumHEXADECIMALNoZero :: HEXADECIMALNoZero d => [d]+enumHEXADECIMALNoZero =+ [ d1 # ()+ , d2 # ()+ , d3 # ()+ , d4 # ()+ , d5 # ()+ , d6 # ()+ , d7 # ()+ , d8 # ()+ , d9 # ()+ , dA # ()+ , dB # ()+ , dC # ()+ , dD # ()+ , dE # ()+ , dF # ()+ ]++-- | @[0..9] ++ [A..F]@+enumHEXADECIMAL :: HEXADECIMAL d => [d]+enumHEXADECIMAL =+ [ d0 # ()+ , d1 # ()+ , d2 # ()+ , d3 # ()+ , d4 # ()+ , d5 # ()+ , d6 # ()+ , d7 # ()+ , d8 # ()+ , d9 # ()+ , dA # ()+ , dB # ()+ , dC # ()+ , dD # ()+ , dE # ()+ , dF # ()+ ]
+ src/Data/Digit/Hexadecimal/LowerCase.hs view
@@ -0,0 +1,129 @@+{-# LANGUAGE NoImplicitPrelude #-}+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE TemplateHaskell #-}++module Data.Digit.Hexadecimal.LowerCase(+ HexDigit(..)+, HexadecimalNoZero+, Hexadecimal+, parseHexadecimalNoZero+, parseHexadecimal+-- * Prisms+, _HexDigit0+, _HexDigit1+, _HexDigit2+, _HexDigit3+, _HexDigit4+, _HexDigit5+, _HexDigit6+, _HexDigit7+, _HexDigit8+, _HexDigit9+, _HexDigita+, _HexDigitb+, _HexDigitc+, _HexDigitd+, _HexDigite+, _HexDigitf+-- * Re-exports+, module Data.Digit.Class.D0+, module Data.Digit.Class.D1+, module Data.Digit.Class.D2+, module Data.Digit.Class.D3+, module Data.Digit.Class.D4+, module Data.Digit.Class.D5+, module Data.Digit.Class.D6+, module Data.Digit.Class.D7+, module Data.Digit.Class.D8+, module Data.Digit.Class.D9++, module Data.Digit.Class.LowerCase+) where++import Prelude (Eq, Show, Ord)+import Control.Lens.TH (makePrisms)+import Text.Parser.Char(CharParsing)+import Text.Parser.Combinators((<?>), choice)++import Data.Digit.Class.D0+import Data.Digit.Class.D1+import Data.Digit.Class.D2+import Data.Digit.Class.D3+import Data.Digit.Class.D4+import Data.Digit.Class.D5+import Data.Digit.Class.D6+import Data.Digit.Class.D7+import Data.Digit.Class.D8+import Data.Digit.Class.D9+import Data.Digit.Class.LowerCase++import Data.Digit.Decimal(parseDecimalNoZero)++data HexDigit+ = HexDigit0+ | HexDigit1+ | HexDigit2+ | HexDigit3+ | HexDigit4+ | HexDigit5+ | HexDigit6+ | HexDigit7+ | HexDigit8+ | HexDigit9+ | HexDigita+ | HexDigitb+ | HexDigitc+ | HexDigitd+ | HexDigite+ | HexDigitf+ deriving (Show, Eq, Ord)++makePrisms ''HexDigit++instance D0 HexDigit where; d0 = _HexDigit0+instance D1 HexDigit where; d1 = _HexDigit1+instance D2 HexDigit where; d2 = _HexDigit2+instance D3 HexDigit where; d3 = _HexDigit3+instance D4 HexDigit where; d4 = _HexDigit4+instance D5 HexDigit where; d5 = _HexDigit5+instance D6 HexDigit where; d6 = _HexDigit6+instance D7 HexDigit where; d7 = _HexDigit7+instance D8 HexDigit where; d8 = _HexDigit8+instance D9 HexDigit where; d9 = _HexDigit9+instance Da HexDigit where; da = _HexDigita+instance Db HexDigit where; db = _HexDigitb+instance Dc HexDigit where; dc = _HexDigitc+instance Dd HexDigit where; dd = _HexDigitd+instance De HexDigit where; de = _HexDigite+instance Df HexDigit where; df = _HexDigitf++type HexadecimalNoZero d =+ (D1 d, D2 d, D3 d, D4 d, D5 d, D6 d, D7 d, D8 d, D9 d, Da d, Db d, Dc d, Dd d, De d, De d, Df d)++parseHexadecimalNoZero ::+ (HexadecimalNoZero d, CharParsing p) =>+ p d+parseHexadecimalNoZero =+ choice+ [+ parseDecimalNoZero+ , parsea+ , parseb+ , parsec+ , parsed+ , parsee+ , parsef+ ] <?> "HexadecimalNoZero"++type Hexadecimal d =+ (D0 d, HexadecimalNoZero d)++parseHexadecimal ::+ (Hexadecimal d, CharParsing p) =>+ p d+parseHexadecimal =+ choice+ [+ parse0+ , parseHexadecimalNoZero+ ] <?> "Hexadecimal"
+ src/Data/Digit/Hexadecimal/MixedCase.hs view
@@ -0,0 +1,144 @@+{-# LANGUAGE NoImplicitPrelude #-}+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE TemplateHaskell #-}++module Data.Digit.Hexadecimal.MixedCase(+ HeXDigit(..)+, HeXaDeCiMaLNoZero+, HeXaDeCiMaL+, parseHeXaDeCiMaLNoZero+, parseHeXaDeCiMaL+-- * Prisms+, _HeXDigit0+, _HeXDigit1+, _HeXDigit2+, _HeXDigit3+, _HeXDigit4+, _HeXDigit5+, _HeXDigit6+, _HeXDigit7+, _HeXDigit8+, _HeXDigit9+, _HeXDigita+, _HeXDigitb+, _HeXDigitc+, _HeXDigitd+, _HeXDigite+, _HeXDigitf+, _HeXDigitA+, _HeXDigitB+, _HeXDigitC+, _HeXDigitD+, _HeXDigitE+, _HeXDigitF+-- * Re-exports+, module Data.Digit.Class.D0+, module Data.Digit.Class.D1+, module Data.Digit.Class.D2+, module Data.Digit.Class.D3+, module Data.Digit.Class.D4+, module Data.Digit.Class.D5+, module Data.Digit.Class.D6+, module Data.Digit.Class.D7+, module Data.Digit.Class.D8+, module Data.Digit.Class.D9+, module Data.Digit.Class.MixedCase+) where++import Prelude (Eq, Show, Ord)+import Control.Lens.TH (makePrisms)+import Text.Parser.Char(CharParsing)+import Text.Parser.Combinators((<?>), choice)+import Data.Digit.Class.D0+import Data.Digit.Class.D1+import Data.Digit.Class.D2+import Data.Digit.Class.D3+import Data.Digit.Class.D4+import Data.Digit.Class.D5+import Data.Digit.Class.D6+import Data.Digit.Class.D7+import Data.Digit.Class.D8+import Data.Digit.Class.D9+import Data.Digit.Class.MixedCase+import Data.Digit.Decimal(parseDecimalNoZero)++data HeXDigit+ = HeXDigit0+ | HeXDigit1+ | HeXDigit2+ | HeXDigit3+ | HeXDigit4+ | HeXDigit5+ | HeXDigit6+ | HeXDigit7+ | HeXDigit8+ | HeXDigit9+ | HeXDigita+ | HeXDigitb+ | HeXDigitc+ | HeXDigitd+ | HeXDigite+ | HeXDigitf+ | HeXDigitA+ | HeXDigitB+ | HeXDigitC+ | HeXDigitD+ | HeXDigitE+ | HeXDigitF+ deriving (Show, Eq, Ord)++makePrisms ''HeXDigit++instance D0 HeXDigit where; d0 = _HeXDigit0+instance D1 HeXDigit where; d1 = _HeXDigit1+instance D2 HeXDigit where; d2 = _HeXDigit2+instance D3 HeXDigit where; d3 = _HeXDigit3+instance D4 HeXDigit where; d4 = _HeXDigit4+instance D5 HeXDigit where; d5 = _HeXDigit5+instance D6 HeXDigit where; d6 = _HeXDigit6+instance D7 HeXDigit where; d7 = _HeXDigit7+instance D8 HeXDigit where; d8 = _HeXDigit8+instance D9 HeXDigit where; d9 = _HeXDigit9+instance DA HeXDigit where; dA = _HeXDigitA+instance Da HeXDigit where; da = _HeXDigita+instance DB HeXDigit where; dB = _HeXDigitB+instance Db HeXDigit where; db = _HeXDigitb+instance DC HeXDigit where; dC = _HeXDigitC+instance Dc HeXDigit where; dc = _HeXDigitc+instance DD HeXDigit where; dD = _HeXDigitD+instance Dd HeXDigit where; dd = _HeXDigitd+instance DE HeXDigit where; dE = _HeXDigitE+instance De HeXDigit where; de = _HeXDigite+instance DF HeXDigit where; dF = _HeXDigitF+instance Df HeXDigit where; df = _HeXDigitf++type HeXaDeCiMaLNoZero d =+ (D1 d, D2 d, D3 d, D4 d, D5 d, D6 d, D7 d, D8 d, D9 d, DA d, DB d, DC d, DD d, DE d, DF d, Da d, Db d, Dc d, Dd d, De d, De d, Df d)++parseHeXaDeCiMaLNoZero ::+ (HeXaDeCiMaLNoZero d, CharParsing p) =>+ p d+parseHeXaDeCiMaLNoZero =+ choice+ [+ parseDecimalNoZero+ , parseAa+ , parseBb+ , parseCc+ , parseDd+ , parseEe+ , parseFf+ ] <?> "HeXaDeCiMaLNoZero"++type HeXaDeCiMaL d =+ (D0 d, HeXaDeCiMaLNoZero d)++parseHeXaDeCiMaL ::+ (HeXaDeCiMaL d, CharParsing p) =>+ p d+parseHeXaDeCiMaL =+ choice+ [+ parse0+ , parseHeXaDeCiMaLNoZero+ ] <?> "HeXaDeCiMaL"
+ src/Data/Digit/Hexadecimal/UpperCase.hs view
@@ -0,0 +1,126 @@+{-# LANGUAGE NoImplicitPrelude #-}+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE TemplateHaskell #-}++module Data.Digit.Hexadecimal.UpperCase(+ HEXDigit(..)+, HEXADECIMALNoZero+, HEXADECIMAL+, parseHEXADECIMALNoZero+, parseHEXADECIMAL+-- * Prisms+, _HEXDigit0+, _HEXDigit1+, _HEXDigit2+, _HEXDigit3+, _HEXDigit4+, _HEXDigit5+, _HEXDigit6+, _HEXDigit7+, _HEXDigit8+, _HEXDigit9+, _HEXDigitA+, _HEXDigitB+, _HEXDigitC+, _HEXDigitD+, _HEXDigitE+, _HEXDigitF+-- * Re-exports+, module Data.Digit.Class.D0+, module Data.Digit.Class.D1+, module Data.Digit.Class.D2+, module Data.Digit.Class.D3+, module Data.Digit.Class.D4+, module Data.Digit.Class.D5+, module Data.Digit.Class.D6+, module Data.Digit.Class.D7+, module Data.Digit.Class.D8+, module Data.Digit.Class.D9+, module Data.Digit.Class.UpperCase+) where++import Prelude (Eq, Show, Ord)+import Control.Lens.TH (makePrisms)+import Text.Parser.Char(CharParsing)+import Text.Parser.Combinators((<?>), choice)+import Data.Digit.Class.D0+import Data.Digit.Class.D1+import Data.Digit.Class.D2+import Data.Digit.Class.D3+import Data.Digit.Class.D4+import Data.Digit.Class.D5+import Data.Digit.Class.D6+import Data.Digit.Class.D7+import Data.Digit.Class.D8+import Data.Digit.Class.D9+import Data.Digit.Class.UpperCase+import Data.Digit.Decimal(parseDecimalNoZero)++data HEXDigit+ = HEXDigit0+ | HEXDigit1+ | HEXDigit2+ | HEXDigit3+ | HEXDigit4+ | HEXDigit5+ | HEXDigit6+ | HEXDigit7+ | HEXDigit8+ | HEXDigit9+ | HEXDigitA+ | HEXDigitB+ | HEXDigitC+ | HEXDigitD+ | HEXDigitE+ | HEXDigitF+ deriving (Show, Eq, Ord)++makePrisms ''HEXDigit++instance D0 HEXDigit where; d0 = _HEXDigit0+instance D1 HEXDigit where; d1 = _HEXDigit1+instance D2 HEXDigit where; d2 = _HEXDigit2+instance D3 HEXDigit where; d3 = _HEXDigit3+instance D4 HEXDigit where; d4 = _HEXDigit4+instance D5 HEXDigit where; d5 = _HEXDigit5+instance D6 HEXDigit where; d6 = _HEXDigit6+instance D7 HEXDigit where; d7 = _HEXDigit7+instance D8 HEXDigit where; d8 = _HEXDigit8+instance D9 HEXDigit where; d9 = _HEXDigit9+instance DA HEXDigit where; dA = _HEXDigitA+instance DB HEXDigit where; dB = _HEXDigitB+instance DC HEXDigit where; dC = _HEXDigitC+instance DD HEXDigit where; dD = _HEXDigitD+instance DE HEXDigit where; dE = _HEXDigitE+instance DF HEXDigit where; dF = _HEXDigitF++type HEXADECIMALNoZero d =+ (D1 d, D2 d, D3 d, D4 d, D5 d, D6 d, D7 d, D8 d, D9 d, DA d, DB d, DC d, DD d, DE d, DF d)++parseHEXADECIMALNoZero ::+ (HEXADECIMALNoZero d, CharParsing p) =>+ p d+parseHEXADECIMALNoZero =+ choice+ [+ parseDecimalNoZero+ , parseA+ , parseB+ , parseC+ , parseD+ , parseE+ , parseF+ ] <?> "HEXADECIMALNoZero"++type HEXADECIMAL d =+ (D0 d, HEXADECIMALNoZero d)++parseHEXADECIMAL ::+ (HEXADECIMAL d, CharParsing p) =>+ p d+parseHEXADECIMAL =+ choice+ [+ parse0+ , parseHEXADECIMALNoZero+ ] <?> "HEXADECIMAL"
+ src/Data/Digit/Integral.hs view
@@ -0,0 +1,549 @@+{-# LANGUAGE NoImplicitPrelude #-}++module Data.Digit.Integral(+-- * Binary+ integralBinaryNoZero+, integralBinary+, integralBinDigits+, binDigitsIntegral+-- * Octal+, integralOctalNoZero+, integralOctal+, integralOctDigits+, octDigitsIntegral+-- * Decimal+, integralDecimal+, integralDecimalNoZero+, integralDecDigits+, decDigitsIntegral+-- * Hexadecimal+, integralHexadecimalNoZero+, integralHexadecimal+, integralHexDigits+, hexDigitsIntegral+-- * HEXADECIMAL+, integralHEXADECIMALNoZero+, integralHEXADECIMAL+, integralHEXDigits+, _HEXDigitsIntegral+-- * HeXaDeCiMaL+, integralHeXaDeCiMaLNoZero+, integralHeXaDeCiMaL+, _HeXDigitsIntegral+, mod10+, addDecDigit+, addDecDigit'+) where++import Prelude (Eq, Integral, error, fst, lookup,+ quotRem, (*), (+), (-), (==), (>=), mod, divMod)++import Control.Applicative (Applicative)+import Control.Category (id, (.))+import Control.Lens (APrism, Choice, Prism', Review,+ clonePrism, outside, prism', unto, over, _1,+ ( # ), (.~), (^?!), (^?))+import Control.Lens.Extras (is)++import Data.Bool (Bool, bool)+import Data.Either (Either (..), either)+import Data.Foldable (find, foldl')+import Data.Function (($),const)+import Data.Functor ((<$>))+import Data.Int (Int)+import Data.List.NonEmpty (NonEmpty)+import Data.Maybe (fromMaybe)+import Data.Ord ((>))++import Data.Digit.Binary+import Data.Digit.Decimal+import Data.Digit.Hexadecimal.LowerCase+import Data.Digit.Hexadecimal.UpperCase+import Data.Digit.Hexadecimal.MixedCase+import Data.Digit.Octal+import qualified Data.List.NonEmpty as NonEmpty++-- $setup+-- >>> import Data.Digit++-- |+--+-- >>> 1 ^? integralBinaryNoZero+-- Just BinDigit1+--+-- >>> integralBinaryNoZero # BinDigit1 :: Integer+-- 1+integralBinaryNoZero ::+ (Integral a, BinaryNoZero d) =>+ Prism'+ a+ d+integralBinaryNoZero =+ associatePrism (1, d1) []++-- |+--+-- >>> 0 ^? integralBinary :: Maybe BinDigit+-- Just BinDigit0+--+-- >>> integralBinary # BinDigit0 :: Integer+-- 0+integralBinary ::+ (Integral a, Binary d) =>+ Prism'+ a+ d+integralBinary =+ associatePrism (0, d0) [(1, d1)]++-- |+-- >>> integralBinDigits (4 :: Int)+-- Right (BinDigit1 :| [BinDigit0, BinDigit0])+--+-- >>> integralBinDigits (0 :: Int)+-- Right (BinDigit0 :| [])+--+-- >>> integralBinDigits (-1 :: Int)+-- Left (BinDigit0 :| [])+--+-- >>> integralBinDigits (-4 :: Int)+-- Left (BinDigit1 :| [BinDigit1])+integralBinDigits :: Integral a => a -> Either (NonEmpty BinDigit) (NonEmpty BinDigit)+integralBinDigits n =+ if n >= 0+ then Right . NonEmpty.fromList $ go n []+ else Left . NonEmpty.fromList $ go (-n - 1) []+ where+ go k =+ let+ (q, r) = quotRem k 2+ in+ (if q == 0 then id else go q) . ((r ^?! integralBinary) :)++-- |+-- >>> binDigitsIntegral (Right (BinDigit1 :| [BinDigit0, BinDigit0])) :: Int+-- 4+--+-- >>> binDigitsIntegral (Right (BinDigit0 :| [])) :: Int+-- 0+--+-- >>> binDigitsIntegral (Left (BinDigit0 :| [])) :: Int+-- 0+--+-- >>> binDigitsIntegral (Left (BinDigit1 :| [BinDigit1])) :: Int+-- -3+binDigitsIntegral :: Integral a => Either (NonEmpty BinDigit) (NonEmpty BinDigit) -> a+binDigitsIntegral = either (\n -> -(go n)) go+ where+ go = foldl' (\b a -> (integralBinary # a) + 2 * b) 0++-- |+--+-- >>> 7 ^? integralOctalNoZero :: Maybe OctDigit+-- Just OctDigit7+--+-- >>> integralOctalNoZero # OctDigit7 :: Integer+-- 7+integralOctalNoZero ::+ (Integral a, OctalNoZero d) =>+ Prism'+ a+ d+integralOctalNoZero =+ associatePrism (1, d1) [(2, d2), (3, d3), (4, d4), (5, d5), (6, d6), (7, d7)]++-- |+--+-- >>> 7 ^? integralOctal :: Maybe OctDigit+-- Just OctDigit7+--+-- >>> integralOctal # OctDigit7 :: Integer+-- 7+integralOctal ::+ (Integral a, Octal d) =>+ Prism'+ a+ d+integralOctal =+ associatePrism (0, d0) [(1, d1), (2, d2), (3, d3), (4, d4), (5, d5), (6, d6), (7, d7)]++-- |+-- >>> integralOctDigits (64 :: Int)+-- Right (OctDigit1 :| [OctDigit0, OctDigit0])+--+-- >>> integralOctDigits (0 :: Int)+-- Right (OctDigit0 :| [])+--+-- >>> integralOctDigits (-1 :: Int)+-- Left (OctDigit0 :| [])+--+-- >>> integralOctDigits (-64 :: Int)+-- Left (OctDigit7 :| [OctDigit7])+integralOctDigits :: Integral a => a -> Either (NonEmpty OctDigit) (NonEmpty OctDigit)+integralOctDigits n =+ if n >= 0+ then Right . NonEmpty.fromList $ go n []+ else Left . NonEmpty.fromList $ go (-n - 1) []+ where+ go k =+ let+ (q, r) = quotRem k 8+ in+ (if q == 0 then id else go q) . ((r ^?! integralOctal) :)++-- |+-- >>> octDigitsIntegral (Right (OctDigit1 :| [OctDigit0, OctDigit0])) :: Int+-- 64+--+-- >>> octDigitsIntegral (Right (OctDigit0 :| [])) :: Int+-- 0+--+-- >>> octDigitsIntegral (Left (OctDigit0 :| [])) :: Int+-- 0+--+-- >>> octDigitsIntegral (Left (OctDigit7 :| [OctDigit7])) :: Int+-- -63+octDigitsIntegral :: Integral a => Either (NonEmpty OctDigit) (NonEmpty OctDigit) -> a+octDigitsIntegral = either (\n -> -(go n)) go+ where+ go = foldl' (\b a -> (integralOctal # a) + 8 * b) 0++-- |+-- >>> 9 ^? integralDecimalNoZero :: Maybe DecDigit+-- Just DecDigit9+--+-- >>> integralDecimalNoZero # DecDigit9 :: Integer+-- 9+integralDecimalNoZero ::+ (Integral a, DecimalNoZero d) =>+ Prism'+ a+ d+integralDecimalNoZero =+ associatePrism (1, d1) [(2, d2), (3, d3), (4, d4), (5, d5), (6, d6), (7, d7), (8, d8), (9, d9)]++-- |+-- >>> 9 ^? integralDecimal :: Maybe DecDigit+-- Just DecDigit9+--+-- >>> integralDecimal # DecDigit9 :: Integer+-- 9+integralDecimal ::+ (Integral a, Decimal d) =>+ Prism'+ a+ d+integralDecimal =+ associatePrism (0, d0) [(1, d1), (2, d2), (3, d3), (4, d4), (5, d5), (6, d6), (7, d7), (8, d8), (9, d9)]++-- |+-- >>> integralDecDigits (100 :: Int)+-- Right (DecDigit1 :| [DecDigit0, DecDigit0])+--+-- >>> integralDecDigits (0 :: Int)+-- Right (DecDigit0 :| [])+--+-- >>> integralDecDigits (-1 :: Int)+-- Left (DecDigit0 :| [])+--+-- >>> integralDecDigits (-100 :: Int)+-- Left (DecDigit9 :| [DecDigit9])+integralDecDigits :: Integral a => a -> Either (NonEmpty DecDigit) (NonEmpty DecDigit)+integralDecDigits n =+ if n >= 0+ then Right . NonEmpty.fromList $ go n []+ else Left . NonEmpty.fromList $ go (-n - 1) []+ where+ go k =+ let+ (q, r) = quotRem k 10+ in+ (if q == 0 then id else go q) . ((r ^?! integralDecimal) :)++-- |+-- >>> decDigitsIntegral (Right (DecDigit1 :| [DecDigit0, DecDigit0])) :: Int+-- 100+--+-- >>> decDigitsIntegral (Right (DecDigit0 :| [])) :: Int+-- 0+--+-- >>> decDigitsIntegral (Left (DecDigit0 :| [])) :: Int+-- 0+--+-- >>> decDigitsIntegral (Left (DecDigit9 :| [DecDigit9])) :: Int+-- -9+decDigitsIntegral :: Integral a => Either (NonEmpty DecDigit) (NonEmpty DecDigit) -> a+decDigitsIntegral = either (\n -> -(go n)) go+ where+ go = foldl' (\b a -> (integralDecimal # a) + 10 * b) 0++-- |+--+-- >>> 15 ^? integralHexadecimalNoZero :: Maybe HexDigit+-- Just HexDigitf+--+-- >>> integralHexadecimalNoZero # HexDigitf :: Integer+-- 15+integralHexadecimalNoZero ::+ (Integral a, HexadecimalNoZero d) =>+ Prism'+ a+ d+integralHexadecimalNoZero =+ associatePrism (1, d1) [(2, d2), (3, d3), (4, d4), (5, d5), (6, d6), (7, d7), (8, d8), (9, d9), (10, da), (11, db), (12, dc), (13, dd), (14, de), (15, df)]++-- |+--+-- >>> 15 ^? integralHexadecimal :: Maybe HexDigit+-- Just HexDigitf+--+-- >>> integralHexadecimal # HexDigitf :: Integer+-- 15+integralHexadecimal ::+ (Integral a, Hexadecimal d) =>+ Prism'+ a+ d+integralHexadecimal =+ associatePrism (0, d0) [(1, d1), (2, d2), (3, d3), (4, d4), (5, d5), (6, d6), (7, d7), (8, d8), (9, d9), (10, da), (11, db), (12, dc), (13, dd), (14, de), (15, df)]++-- |+-- >>> integralHexDigits (256 :: Int)+-- Right (HexDigit1 :| [HexDigit0, HexDigit0])+--+-- >>> integralHexDigits (0 :: Int)+-- Right (HexDigit0 :| [])+--+-- >>> integralHexDigits (-1 :: Int)+-- Left (HexDigit0 :| [])+--+-- >>> integralHexDigits (-256 :: Int)+-- Left (HexDigitf :| [HexDigitf])+integralHexDigits :: Integral a => a -> Either (NonEmpty HexDigit) (NonEmpty HexDigit)+integralHexDigits n =+ if n >= 0+ then Right . NonEmpty.fromList $ go n []+ else Left . NonEmpty.fromList $ go (-n - 1) []+ where+ go k =+ let+ (q, r) = quotRem k 16+ in+ (if q == 0 then id else go q) . ((r ^?! integralHexadecimal) :)++-- |+-- >>> hexDigitsIntegral (Right (HexDigit1 :| [HexDigit0, HexDigit0])) :: Int+-- 256+--+-- >>> hexDigitsIntegral (Right (HexDigit0 :| [])) :: Int+-- 0+--+-- >>> hexDigitsIntegral (Left (HexDigit0 :| [])) :: Int+-- 0+--+-- >>> hexDigitsIntegral (Left (HexDigitf :| [HexDigitf])) :: Int+-- -255+hexDigitsIntegral :: Integral a => Either (NonEmpty HexDigit) (NonEmpty HexDigit) -> a+hexDigitsIntegral = either (\n -> -(go n)) go+ where+ go = foldl' (\b a -> (integralHexadecimal # a) + 16 * b) 0++-- |+--+-- >>> 15 ^? integralHEXADECIMALNoZero :: Maybe HEXDigit+-- Just HEXDigitF+--+-- >>> integralHEXADECIMALNoZero # HEXDigitF :: Integer+-- 15+integralHEXADECIMALNoZero ::+ (Integral a, HEXADECIMALNoZero d) =>+ Prism'+ a+ d+integralHEXADECIMALNoZero =+ associatePrism (1, d1) [(2, d2), (3, d3), (4, d4), (5, d5), (6, d6), (7, d7), (8, d8), (9, d9), (10, dA), (11, dB), (12, dC), (13, dD), (14, dE), (15, dF)]+++-- |+--+-- >>> 15 ^? integralHEXADECIMAL :: Maybe HEXDigit+-- Just HEXDigitF+--+-- >>> integralHEXADECIMAL # HEXDigitF :: Integer+-- 15+integralHEXADECIMAL ::+ (Integral a, HEXADECIMAL d) =>+ Prism'+ a+ d+integralHEXADECIMAL =+ associatePrism (0, d0) [(1, d1), (2, d2), (3, d3), (4, d4), (5, d5), (6, d6), (7, d7), (8, d8), (9, d9), (10, dA), (11, dB), (12, dC), (13, dD), (14, dE), (15, dF)]++-- |+-- >>> integralHEXDigits (256 :: Int)+-- Right (HEXDigit1 :| [HEXDigit0, HEXDigit0])+--+-- >>> integralHEXDigits (0 :: Int)+-- Right (HEXDigit0 :| [])+--+-- >>> integralHEXDigits (-1 :: Int)+-- Left (HEXDigit0 :| [])+--+-- >>> integralHEXDigits (-256 :: Int)+-- Left (HEXDigitF :| [HEXDigitF])+integralHEXDigits :: Integral a => a -> Either (NonEmpty HEXDigit) (NonEmpty HEXDigit)+integralHEXDigits n =+ if n >= 0+ then Right . NonEmpty.fromList $ go n []+ else Left . NonEmpty.fromList $ go (-n - 1) []+ where+ go k =+ let+ (q, r) = quotRem k 16+ in+ (if q == 0 then id else go q) . ((r ^?! integralHEXADECIMAL) :)++-- |+-- >>> _HEXDigitsIntegral (Right (HEXDigit1 :| [HEXDigit0, HEXDigit0])) :: Int+-- 256+--+-- >>> _HEXDigitsIntegral (Right (HEXDigit0 :| [])) :: Int+-- 0+--+-- >>> _HEXDigitsIntegral (Left (HEXDigit0 :| [])) :: Int+-- 0+--+-- >>> _HEXDigitsIntegral (Left (HEXDigitF :| [HEXDigitF])) :: Int+-- -255+_HEXDigitsIntegral :: Integral a => Either (NonEmpty HEXDigit) (NonEmpty HEXDigit) -> a+_HEXDigitsIntegral = either (\n -> -(go n)) go+ where+ go = foldl' (\b a -> (integralHEXADECIMAL # a) + 16 * b) 0++-- |+--+-- >>> 15 ^? integralHeXaDeCiMaLNoZero :: Maybe HeXDigit+-- Just HeXDigitF+--+-- >>> integralHeXaDeCiMaLNoZero # HeXDigitF :: Integer+-- 15+integralHeXaDeCiMaLNoZero ::+ (Integral a, HeXaDeCiMaLNoZero d) =>+ Review+ a+ d+integralHeXaDeCiMaLNoZero =+ unto+ (outside d1 .~ const 1 $+ outside d2 .~ const 2 $+ outside d3 .~ const 3 $+ outside d4 .~ const 4 $+ outside d5 .~ const 5 $+ outside d6 .~ const 6 $+ outside d7 .~ const 7 $+ outside d8 .~ const 8 $+ outside d9 .~ const 9 $+ outside da .~ const 10 $+ outside dA .~ const 10 $+ outside db .~ const 11 $+ outside dB .~ const 11 $+ outside dc .~ const 12 $+ outside dC .~ const 12 $+ outside dd .~ const 13 $+ outside dD .~ const 13 $+ outside de .~ const 14 $+ outside dE .~ const 14 $+ outside df .~ const 15 $+ outside dF .~ const 15 $+ error "incomplete pattern")++-- |+--+-- >>> 15 ^? integralHeXaDeCiMaL :: Maybe HeXDigit+-- Just HeXDigitF+--+-- >>> integralHeXaDeCiMaL # HeXDigitF :: Integer+-- 15+integralHeXaDeCiMaL ::+ (Integral a, HeXaDeCiMaL d) =>+ Review+ a+ d+integralHeXaDeCiMaL =+ unto+ (outside d0 .~ const 0 $+ outside d1 .~ const 1 $+ outside d2 .~ const 2 $+ outside d3 .~ const 3 $+ outside d4 .~ const 4 $+ outside d5 .~ const 5 $+ outside d6 .~ const 6 $+ outside d7 .~ const 7 $+ outside d8 .~ const 8 $+ outside d9 .~ const 9 $+ outside da .~ const 10 $+ outside dA .~ const 10 $+ outside db .~ const 11 $+ outside dB .~ const 11 $+ outside dc .~ const 12 $+ outside dC .~ const 12 $+ outside dd .~ const 13 $+ outside dD .~ const 13 $+ outside de .~ const 14 $+ outside dE .~ const 14 $+ outside df .~ const 15 $+ outside dF .~ const 15 $+ error "incomplete pattern")++-- |+-- >>> _HeXDigitsIntegral (Right (HeXDigit1 :| [HeXDigit0, HeXDigit0])) :: Int+-- 256+--+-- >>> _HeXDigitsIntegral (Right (HeXDigit0 :| [])) :: Int+-- 0+--+-- >>> _HeXDigitsIntegral (Left (HeXDigit0 :| [])) :: Int+-- 0+--+-- >>> _HeXDigitsIntegral (Left (HeXDigitF :| [HeXDigitF])) :: Int+-- -255+_HeXDigitsIntegral :: Integral a => Either (NonEmpty HeXDigit) (NonEmpty HeXDigit) -> a+_HeXDigitsIntegral = either (\n -> -(go n)) go+ where+ go = foldl' (\b a -> (integralHeXaDeCiMaL # a) + 16 * b) 0++mod10 ::+ Integral a =>+ a+ -> DecDigit+mod10 n =+ let r = n `mod` 10+ in fromMaybe (mod10 r) (r ^? integralDecimal)++addDecDigit ::+ DecDigit+ -> DecDigit+ -> (Bool, DecDigit)+addDecDigit a b =+ let (x, r) =+ (integralDecimal # a + integralDecimal # b) `divMod` 10+ in (x > 0, mod10 (r :: Int))++addDecDigit' ::+ DecDigit+ -> DecDigit+ -> (DecDigit, DecDigit)+addDecDigit' a b =+ over _1 (bool x0 x1) (addDecDigit a b)++---- not exported+associatePrism ::+ (Eq b, Choice p, Applicative f) =>+ (b, APrism a a () ())+ -> [(b, APrism a a () ())]+ -> p a (f a)+ -> p b (f b)+associatePrism def z =+ prism'+ (\d -> fst (fromMaybe def (find (\(_, w) -> is w d) z)))+ (\i -> (\p -> clonePrism p # ()) <$> lookup i (def:z))
+ src/Data/Digit/Natural.hs view
@@ -0,0 +1,116 @@+module Data.Digit.Natural+ ( _NaturalDigits+ , naturalToDigits+ , digitsToNatural+ ) where++import Prelude (Int, error, fromIntegral, maxBound, (*),+ (+), (-), (>), (^))++import Control.Category ((.))+import Control.Lens (Prism', ifoldrM, prism', ( # ))++import Data.Foldable (length)+import Data.Function (($))+import Data.Functor (fmap, (<$>))+import Data.Semigroup ((<>))++import Data.List (replicate)++import Data.List.NonEmpty (NonEmpty ((:|)))+import qualified Data.List.NonEmpty as NE++import Data.Maybe (Maybe (..))++import Data.Digit.Decimal+import Data.Digit.Integral (integralDecimal)++import Numeric.Natural (Natural)++import Data.Scientific (toDecimalDigits)++-- |+--+-- >>> _NaturalDigits # 0+-- DecDigit0 :| []+--+-- >>> _NaturalDigits # 1+-- DecDigit1 :| []+--+-- >>> _NaturalDigits # 922+-- DecDigit9 :| [DecDigit2,DecDigit2]+--+-- >>> (DecDigit9 :| [DecDigit2,DecDigit2]) ^? _NaturalDigits+-- Just 922+--+-- >>> (DecDigit1 :| []) ^? _NaturalDigits+-- Just 1+--+-- prop> \x -> digitsToNatural ( naturalToDigits x ) == Just x+--+_NaturalDigits :: Prism' (NonEmpty DecDigit) Natural+_NaturalDigits = prism' naturalToDigits digitsToNatural++-- |+--+-- >>> naturalDigits 0+-- DecDigit0 :| []+--+-- >>> naturalDigits 9+-- DecDigit9 :| []+--+-- >>> naturalDigits 393+-- DecDigit3 :| [DecDigit9,DecDigit3]+--+naturalToDigits :: Natural -> NonEmpty DecDigit+naturalToDigits n =+ case toDecimalDigits $ fromIntegral n of+ -- toDecimalDigits :: n -> ([n],n)+ -- toDecimalDigits 0 = ([0],0)+ -- toDecimalDigits (-0) = ([0],0)+ -- toDecimalDigits (-1) = ([-1],1)+ ([], _ ) -> error "Data.Scientific.toDecimalDigits is no longer correct!"+ (x:xs, eXP) -> g x :| (g <$> xs) <> t (x:xs) eXP++ where+ t allDigs eXP =+ replicate (eXP - length allDigs) (d0 # ())++ -- EWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW!+ -- But you can't reach this point unless you have a non-zero absolute integral value. So... I dunno.+ g 0 = d0 # ()+ g 1 = d1 # ()+ g 2 = d2 # ()+ g 3 = d3 # ()+ g 4 = d4 # ()+ g 5 = d5 # ()+ g 6 = d6 # ()+ g 7 = d7 # ()+ g 8 = d8 # ()+ g 9 = d9 # ()+ g _ = error "The universe now has more than ten digits."++-- | Create a number from a list of digits with the integer bounds of the machine.+--+-- >>> digitsToNatural (DecDigit3 :| [DecDigit4])+-- Just 34+--+-- >>> digitsToNatural (DecDigit0 :| [])+-- Just 0+--+-- >>> digitsToNatural (naturalToDigits (maxBound :: Natural))+-- Just 9223372036854775807+--+-- >>> digitsToNatural (naturalToDigits $ (maxBound :: Natural) + 1)+-- Nothing+digitsToNatural :: NonEmpty DecDigit -> Maybe Natural+digitsToNatural = fmap fromIntegral . ifoldrM f 0 . NE.reverse+ where+ f :: Int -> DecDigit -> Int -> Maybe Int+ f i d curr =+ let+ next = (integralDecimal # d) * (10 ^ i)+ in+ if curr > maxBound - next+ then Nothing+ else Just (curr + next)
+ src/Data/Digit/Octal.hs view
@@ -0,0 +1,95 @@+{-# LANGUAGE NoImplicitPrelude #-}+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE TemplateHaskell #-}++module Data.Digit.Octal(+ OctDigit(..)+, OctalNoZero+, Octal+, parseOctalNoZero+, parseOctal+-- * Prisms+, _OctDigit0+, _OctDigit1+, _OctDigit2+, _OctDigit3+, _OctDigit4+, _OctDigit5+, _OctDigit6+, _OctDigit7+-- * Re-exports+, module Data.Digit.Class.D0+, module Data.Digit.Class.D1+, module Data.Digit.Class.D2+, module Data.Digit.Class.D3+, module Data.Digit.Class.D4+, module Data.Digit.Class.D5+, module Data.Digit.Class.D6+, module Data.Digit.Class.D7+) where++import Prelude (Eq, Show, Ord, Enum, Bounded)+import Control.Lens.TH (makePrisms)+import Text.Parser.Char(CharParsing)+import Text.Parser.Combinators((<?>), choice)+import Data.Digit.Class.D0+import Data.Digit.Class.D1+import Data.Digit.Class.D2+import Data.Digit.Class.D3+import Data.Digit.Class.D4+import Data.Digit.Class.D5+import Data.Digit.Class.D6+import Data.Digit.Class.D7++data OctDigit+ = OctDigit0+ | OctDigit1+ | OctDigit2+ | OctDigit3+ | OctDigit4+ | OctDigit5+ | OctDigit6+ | OctDigit7+ deriving (Show, Eq, Ord, Enum, Bounded)++makePrisms ''OctDigit++instance D0 OctDigit where; d0 = _OctDigit0+instance D1 OctDigit where; d1 = _OctDigit1+instance D2 OctDigit where; d2 = _OctDigit2+instance D3 OctDigit where; d3 = _OctDigit3+instance D4 OctDigit where; d4 = _OctDigit4+instance D5 OctDigit where; d5 = _OctDigit5+instance D6 OctDigit where; d6 = _OctDigit6+instance D7 OctDigit where; d7 = _OctDigit7++type OctalNoZero d =+ (D1 d, D2 d, D3 d, D4 d, D5 d, D6 d, D7 d)++parseOctalNoZero ::+ (OctalNoZero d, CharParsing p) =>+ p d+parseOctalNoZero =+ choice+ [+ parse1+ , parse2+ , parse3+ , parse4+ , parse5+ , parse6+ , parse7+ ] <?> "OctalNoZero"++type Octal d =+ (D0 d, OctalNoZero d)++parseOctal ::+ (Octal d, CharParsing p) =>+ p d+parseOctal =+ choice+ [+ parse0+ , parseOctalNoZero+ ] <?> "Octal"
+ test/Main.hs view
@@ -0,0 +1,307 @@+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE NoImplicitPrelude #-}+module Main(+ main+) where++import Data.Digit+import Numeric.Natural (Natural)+import Prelude (Char, Integral, Int, String, Eq, Show, IO, Integer, minBound, maxBound, fromIntegral,fst,notElem)++import Control.Category ((.))+import Control.Monad ((>>=))+import Control.Applicative ((<*))+import Control.Lens (Prism', (^?), (#))++import Data.Semigroup ((<>))+import Data.Monoid (mconcat)+import Data.Functor ((<$>),fmap)+import Data.Function (($))+import Data.Maybe (Maybe (..))+import Data.Either (Either (..),isLeft)+import Data.List.NonEmpty (NonEmpty)++import Hedgehog(Property, Gen, forAll, property, assert, (===))++import Test.Tasty(TestTree, defaultMain, testGroup)+import Test.Tasty.Hedgehog(testProperty)+import Test.Tasty.HUnit(testCase, (@?=))+import qualified Hedgehog.Gen as Gen+import qualified Hedgehog.Range as Range+import Text.Parsec(parse, ParseError, Parsec, eof)++testPrism ::+ (Show x, Eq x) =>+ Gen x+ -> String+ -> Prism' x HeXDigit+ -> [(x, HeXDigit)]+ -> [TestTree]+testPrism g n p x =+ testProperty+ (n <> " prism invalid values")+ (+ property $+ do c <- forAll . Gen.filter (`notElem` (fmap fst x)) $ g+ (c ^? p :: Maybe HeXDigit) === Nothing+ ) :+ (+ x >>= \(c, d) ->+ [+ testCase+ (n <> " prism ->")+ ((c ^? p :: Maybe HeXDigit) @?= Just d)+ , testCase+ (n <> " prism <-")+ (p # d @?= c)+ ]+ )++testParser ::+ String+ -> Parsec String () HeXDigit+ -> [(Char, HeXDigit)]+ -> [TestTree]+testParser n p x =+ (+ let n' = n <> " parser invalid values"+ in testProperty+ n'+ (+ property $+ do c <- forAll . Gen.filter (`notElem` (fmap fst x)) . Gen.choice $ [Gen.hexit, Gen.unicode]+ assert (isLeft (parse p (n' <> " test") [c] :: Either ParseError HeXDigit))+ )+ ) :+ (+ x >>= \(c, d) ->+ [+ let n' = n <> " parses exactly one character"+ in testCase+ n'+ ((parse (p <* eof) (n' <> " test") [c] :: Either ParseError HeXDigit) @?= Right d)+ , let n' = n <> " parses the correct digit"+ in testCase+ n'+ ((parse p (n' <> "test") (c:"xyz") :: Either ParseError HeXDigit) @?= Right d)+ ]+ )++integralPrism ::+ (Show n, Integral n) =>+ String+ -> Prism' n HeXDigit+ -> [(n, HeXDigit)]+ -> [TestTree]+integralPrism =+ testPrism (Gen.choice [Gen.integral (Range.linear 0 9), Gen.integral (Range.linear 10 99999), Gen.integral (Range.linear (-1) (-99999))])++charPrism ::+ String+ -> Prism' Char HeXDigit+ -> [(Char, HeXDigit)]+ -> [TestTree]+charPrism =+ testPrism (Gen.choice [Gen.hexit, Gen.unicode])++genNatural :: Gen Natural+genNatural = fromIntegral <$> Gen.integral (Range.linear 0 (maxBound :: Int))++prop_natural_digits_roundtrip :: Property+prop_natural_digits_roundtrip = property $ do+ n <- forAll genNatural+ digitsToNatural (naturalToDigits n) === Just n++digitNaturalTests :: TestTree+digitNaturalTests = testGroup "digit Natural tests"+ [ testProperty "Natural <-> NonEmpty Digit" prop_natural_digits_roundtrip+ ]++prop_integer_X :: (Integer -> a) -> (a -> Integer) -> Property+prop_integer_X iToX xToI =+ property $ do+ n <- forAll .+ Gen.integral $+ Range.constant+ (fromIntegral (minBound :: Int))+ (fromIntegral (maxBound :: Int))+ xToI (iToX n) === n++prop_X_integer+ :: (Eq a, Show a)+ => Gen a+ -> (Integer -> Either (NonEmpty a) (NonEmpty a))+ -> (Either (NonEmpty a) (NonEmpty a) -> Integer)+ -> Property+prop_X_integer genX iToX xToI =+ property $ do+ let digits = Gen.nonEmpty (Range.constant 1 50) genX+ ds <- forAll $ Gen.choice [Left <$> digits, Right <$> digits]+ xToI (iToX (xToI ds)) === xToI ds++toFromIntegralTests :: TestTree+toFromIntegralTests =+ testGroup "To and from integers"+ [ testProperty "Integer <-> BinDigit" $+ prop_integer_X integralBinDigits binDigitsIntegral+ , testProperty "BinDigit <-> Integer" $+ prop_X_integer (Gen.element enumBinary) integralBinDigits binDigitsIntegral+ , testProperty "Integer <-> OctDigit" $+ prop_integer_X integralOctDigits octDigitsIntegral+ , testProperty "OctDigit <-> Integer" $+ prop_X_integer (Gen.element enumOctal) integralOctDigits octDigitsIntegral+ , testProperty "Integer <-> DecDigit" $+ prop_integer_X integralDecDigits decDigitsIntegral+ , testProperty "DecDigit <-> Integer" $+ prop_X_integer (Gen.element enumDecimal) integralDecDigits decDigitsIntegral+ , testProperty "Integer <-> HexDigit" $+ prop_integer_X integralHexDigits hexDigitsIntegral+ , testProperty "HexDigit <-> Integer" $+ prop_X_integer (Gen.element enumHexadecimal) integralHexDigits hexDigitsIntegral+ , testProperty "Integer <-> HEXDigit" $+ prop_integer_X integralHEXDigits _HEXDigitsIntegral+ , testProperty "HEXDigit <-> Integer" $+ prop_X_integer (Gen.element enumHEXADECIMAL) integralHEXDigits _HEXDigitsIntegral+ ]++main ::+ IO ()+main = defaultMain $+ testGroup "All Digit Tests"+ [ digitBaseTests+ , digitNaturalTests+ , toFromIntegralTests+ ]++digitBaseTests :: TestTree+digitBaseTests =+ testGroup "digit parser/prism tests" $+ let q0 = ('0', HeXDigit0)+ q1 = ('1', HeXDigit1)+ q2 = ('2', HeXDigit2)+ q3 = ('3', HeXDigit3)+ q4 = ('4', HeXDigit4)+ q5 = ('5', HeXDigit5)+ q6 = ('6', HeXDigit6)+ q7 = ('7', HeXDigit7)+ q8 = ('8', HeXDigit8)+ q9 = ('9', HeXDigit9)+ qa = ('a', HeXDigita)+ qb = ('b', HeXDigitb)+ qc = ('c', HeXDigitc)+ qd = ('d', HeXDigitd)+ qe = ('e', HeXDigite)+ qf = ('f', HeXDigitf)+ qA = ('A', HeXDigitA)+ qB = ('B', HeXDigitB)+ qC = ('C', HeXDigitC)+ qD = ('D', HeXDigitD)+ qE = ('E', HeXDigitE)+ qF = ('F', HeXDigitF)+ r0 :: (Integer, HeXDigit)+ r0 = (0 , HeXDigit0)+ r1 :: (Integer, HeXDigit)+ r1 = (1 , HeXDigit1)+ r2 :: (Integer, HeXDigit)+ r2 = (2 , HeXDigit2)+ r3 :: (Integer, HeXDigit)+ r3 = (3 , HeXDigit3)+ r4 :: (Integer, HeXDigit)+ r4 = (4 , HeXDigit4)+ r5 :: (Integer, HeXDigit)+ r5 = (5 , HeXDigit5)+ r6 :: (Integer, HeXDigit)+ r6 = (6 , HeXDigit6)+ r7 :: (Integer, HeXDigit)+ r7 = (7 , HeXDigit7)+ r8 :: (Integer, HeXDigit)+ r8 = (8 , HeXDigit8)+ r9 :: (Integer, HeXDigit)+ r9 = (9 , HeXDigit9)+ ra :: (Integer, HeXDigit)+ ra = (10 , HeXDigita)+ rb :: (Integer, HeXDigit)+ rb = (11 , HeXDigitb)+ rc :: (Integer, HeXDigit)+ rc = (12 , HeXDigitc)+ rd :: (Integer, HeXDigit)+ rd = (13 , HeXDigitd)+ re :: (Integer, HeXDigit)+ re = (14 , HeXDigite)+ rf :: (Integer, HeXDigit)+ rf = (15 , HeXDigitf)+ rA :: (Integer, HeXDigit)+ rA = (10 , HeXDigitA)+ rB :: (Integer, HeXDigit)+ rB = (11 , HeXDigitB)+ rC :: (Integer, HeXDigit)+ rC = (12 , HeXDigitC)+ rD :: (Integer, HeXDigit)+ rD = (13 , HeXDigitD)+ rE :: (Integer, HeXDigit)+ rE = (14 , HeXDigitE)+ rF :: (Integer, HeXDigit)+ rF = (15 , HeXDigitF)+ in mconcat [+ charPrism "charBinaryNoZero" charBinaryNoZero [q1]+ , charPrism "charBinary" charBinary [q0, q1]+ , charPrism "charOctalNoZero" charOctalNoZero [q1, q2, q3, q4, q5, q6, q7]+ , charPrism "charOctal" charOctal [q0, q1, q2, q3, q4, q5, q6, q7]+ , charPrism "charDecimalNoZero" charDecimalNoZero [q1, q2, q3, q4, q5, q6, q7, q8, q9]+ , charPrism "charDecimal" charDecimal [q0, q1, q2, q3, q4, q5, q6, q7, q8, q9]+ , charPrism "charHexadecimalNoZero" charHexadecimalNoZero [q1, q2, q3, q4, q5, q6, q7, q8, q9, qa, qb, qc, qd, qe, qf]+ , charPrism "charHexadecimal" charHexadecimal [q0, q1, q2, q3, q4, q5, q6, q7, q8, q9, qa, qb, qc, qd, qe, qf]+ , charPrism "charHEXADECIMALNoZero" charHEXADECIMALNoZero [q1, q2, q3, q4, q5, q6, q7, q8, q9, qA, qB, qC, qD, qE, qF]+ , charPrism "charHEXADECIMAL" charHEXADECIMAL [q0, q1, q2, q3, q4, q5, q6, q7, q8, q9, qA, qB, qC, qD, qE, qF]+ , charPrism "charHeXaDeCiMaLNoZero" charHeXaDeCiMaLNoZero [q1, q2, q3, q4, q5, q6, q7, q8, q9, qa, qb, qc, qd, qe, qf, qA, qB, qC, qD, qE, qF]+ , charPrism "charHeXaDeCiMaL" charHeXaDeCiMaL [q0, q1, q2, q3, q4, q5, q6, q7, q8, q9, qa, qb, qc, qd, qe, qf, qA, qB, qC, qD, qE, qF]+ , integralPrism "integralBinaryNoZero" integralBinaryNoZero [r1]+ , integralPrism "integralBinary" integralBinary [r0, r1]+ , integralPrism "integralOctalNoZero" integralOctalNoZero [r1, r2, r3, r4, r5, r6, r7]+ , integralPrism "integralOctal" integralOctal [r0, r1, r2, r3, r4, r5, r6, r7]+ , integralPrism "integralDecimalNoZero" integralDecimalNoZero [r1, r2, r3, r4, r5, r6, r7, r8, r9]+ , integralPrism "integralDecimal" integralDecimal [r0, r1, r2, r3, r4, r5, r6, r7, r8, r9]+ , integralPrism "integralHexadecimalNoZero" integralHexadecimalNoZero [r1, r2, r3, r4, r5, r6, r7, r8, r9, ra, rb, rc, rd, re, rf]+ , integralPrism "integralHexadecimal" integralHexadecimal [r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, ra, rb, rc, rd, re, rf]+ , integralPrism "integralHEXADECIMALNoZero" integralHEXADECIMALNoZero [r1, r2, r3, r4, r5, r6, r7, r8, r9, rA, rB, rC, rD, rE, rF]+ , integralPrism "integralHEXADECIMAL" integralHEXADECIMAL [r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, rA, rB, rC, rD, rE, rF] , testParser "parseBinaryNoZero" parseBinaryNoZero [q1]+ , testParser "parseBinary" parseBinary [q0, q1]+ , testParser "parseOctalNoZero" parseOctalNoZero [q1, q2, q3, q4, q5, q6, q7]+ , testParser "parseOctal" parseOctal [q0, q1, q2, q3, q4, q5, q6, q7]+ , testParser "parseDecimalNoZero" parseDecimalNoZero [q1, q2, q3, q4, q5, q6, q7, q8, q9]+ , testParser "parseDecimal" parseDecimal [q0, q1, q2, q3, q4, q5, q6, q7, q8, q9]+ , testParser "parseHexadecimalNoZero" parseHexadecimalNoZero [q1, q2, q3, q4, q5, q6, q7, q8, q9, qa, qb, qc, qd, qe, qf]+ , testParser "parseHexadecimal" parseHexadecimal [q0, q1, q2, q3, q4, q5, q6, q7, q8, q9, qa, qb, qc, qd, qe, qf]+ , testParser "parseHEXADECIMALNoZero" parseHEXADECIMALNoZero [q1, q2, q3, q4, q5, q6, q7, q8, q9, qA, qB, qC, qD, qE, qF]+ , testParser "parseHEXADECIMALDecimal" parseHEXADECIMAL [q0, q1, q2, q3, q4, q5, q6, q7, q8, q9, qA, qB, qC, qD, qE, qF]+ , testParser "parseHeXaDeCiMaLNoZero" parseHeXaDeCiMaLNoZero [q1, q2, q3, q4, q5, q6, q7, q8, q9, qa, qb, qc, qd, qe, qf, qA, qB, qC, qD, qE, qF]+ , testParser "parseHeXaDeCiMaLDecimal" parseHeXaDeCiMaL [q0, q1, q2, q3, q4, q5, q6, q7, q8, q9, qa, qb, qc, qd, qe, qf, qA, qB, qC, qD, qE, qF]+ , testParser "parse0" parse0 [q0]+ , testParser "parse1" parse1 [q1]+ , testParser "parse2" parse2 [q2]+ , testParser "parse3" parse3 [q3]+ , testParser "parse4" parse4 [q4]+ , testParser "parse5" parse5 [q5]+ , testParser "parse6" parse6 [q6]+ , testParser "parse7" parse7 [q7]+ , testParser "parse8" parse8 [q8]+ , testParser "parse9" parse9 [q9]+ , testParser "parsea" parsea [qa]+ , testParser "parseb" parseb [qb]+ , testParser "parsec" parsec [qc]+ , testParser "parsed" parsed [qd]+ , testParser "parsee" parsee [qe]+ , testParser "parsef" parsef [qf]+ , testParser "parseA" parseA [qA]+ , testParser "parseB" parseB [qB]+ , testParser "parseC" parseC [qC]+ , testParser "parseD" parseD [qD]+ , testParser "parseE" parseE [qE]+ , testParser "parseF" parseF [qF]+ , testParser "parseAa" parseAa [qA, qa]+ , testParser "parseBb" parseBb [qB, qb]+ , testParser "parseCc" parseCc [qC, qc]+ , testParser "parseDd" parseDd [qD, qd]+ , testParser "parseEe" parseEe [qE, qe]+ , testParser "parseFf" parseFf [qF, qf]+ ]
− test/doctests.hs
@@ -1,32 +0,0 @@-module Main where--import Build_doctests (deps)-import Control.Applicative-import Control.Monad-import Data.List-import System.Directory-import System.FilePath-import Test.DocTest--main ::- IO ()-main =- getSources >>= \sources -> doctest $- "-isrc"- : "-idist/build/autogen"- : "-optP-include"- : "-optPdist/build/autogen/cabal_macros.h"- : "-hide-all-packages"- : map ("-package="++) deps ++ sources--getSources :: IO [FilePath]-getSources = filter (isSuffixOf ".hs") <$> go "src"- where- go dir = do- (dirs, files) <- getFilesAndDirectories dir- (files ++) . concat <$> mapM go dirs--getFilesAndDirectories :: FilePath -> IO ([FilePath], [FilePath])-getFilesAndDirectories dir = do- c <- map (dir </>) . filter (`notElem` ["..", "."]) <$> getDirectoryContents dir- (,) <$> filterM doesDirectoryExist c <*> filterM doesFileExist c