Skip to content

Commit 70d22dd

Browse files
committed
Resolve haskell#6451: Add alaSet to D.Parsec.Newtypes
1 parent 8c3af19 commit 70d22dd

1 file changed

Lines changed: 36 additions & 2 deletions

File tree

Cabal/Distribution/Parsec/Newtypes.hs

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ module Distribution.Parsec.Newtypes (
1818
Sep (..),
1919
-- ** Type
2020
List,
21+
-- * Set
22+
alaSet,
23+
alaSet',
24+
Set',
2125
-- * Version & License
2226
SpecVersion (..),
2327
TestedWith (..),
@@ -38,10 +42,10 @@ import Distribution.Compiler (CompilerFlavor)
3842
import Distribution.License (License)
3943
import Distribution.Parsec
4044
import Distribution.Pretty
41-
import Distribution.Version
42-
(LowerBound (..), Version, VersionRange, anyVersion, asVersionIntervals, mkVersion)
45+
import Distribution.Version (LowerBound (..), Version, VersionRange, anyVersion, asVersionIntervals, mkVersion)
4346
import Text.PrettyPrint (Doc, comma, fsep, punctuate, vcat, (<+>))
4447

48+
import qualified Data.Set as Set
4549
import qualified Distribution.Compat.CharParsing as P
4650
import qualified Distribution.SPDX as SPDX
4751

@@ -117,6 +121,36 @@ instance (Newtype a b, Sep sep, Parsec b) => Parsec (List sep b a) where
117121
instance (Newtype a b, Sep sep, Pretty b) => Pretty (List sep b a) where
118122
pretty = prettySep (Proxy :: Proxy sep) . map (pretty . (pack :: a -> b)) . unpack
119123

124+
-- | Like 'List', but for 'Set'.
125+
newtype Set' sep b a = Set' { _getSet :: Set a }
126+
127+
-- | 'alaSet' and 'alaSet'' are simply 'Set'' constructor, with additional phantom
128+
-- arguments to constraint the resulting type
129+
--
130+
-- >>> :t alaSet VCat
131+
-- alaSet VCat :: Set a -> Set' VCat (Identity a) a
132+
--
133+
-- >>> :t alaSet' FSep Token
134+
-- alaSet' FSep Token :: Set String -> Set' FSep Token String
135+
--
136+
-- >>> unpack' (alaSet' FSep Token) <$> eitherParsec "foo bar foo"
137+
-- Right (fromList ["bar","foo"])
138+
--
139+
alaSet :: sep -> Set a -> Set' sep (Identity a) a
140+
alaSet _ = Set'
141+
142+
-- | More general version of 'alaSet'.
143+
alaSet' :: sep -> (a -> b) -> Set a -> Set' sep b a
144+
alaSet' _ _ = Set'
145+
146+
instance Newtype (Set a) (Set' sep wrapper a)
147+
148+
instance (Newtype a b, Ord a, Sep sep, Parsec b) => Parsec (Set' sep b a) where
149+
parsec = pack . Set.fromList . map (unpack :: b -> a) <$> parseSep (Proxy :: Proxy sep) parsec
150+
151+
instance (Newtype a b, Sep sep, Pretty b) => Pretty (Set' sep b a) where
152+
pretty = prettySep (Proxy :: Proxy sep) . map (pretty . (pack :: a -> b)) . Set.toList . unpack
153+
120154
-- | Haskell string or @[^ ,]+@
121155
newtype Token = Token { getToken :: String }
122156

0 commit comments

Comments
 (0)