OneTuple 0.2.2.1 → 0.3
raw patch · 5 files changed
+349/−89 lines, 5 filesdep +OneTupledep +base-orphansdep +ghc-primdep ~basedep ~semigroupsPVP ok
version bump matches the API change (PVP)
Dependencies added: OneTuple, base-orphans, ghc-prim, transformers, transformers-compat
Dependency ranges changed: base, semigroups
API changes (from Hackage documentation)
- Data.Tuple.OneTuple: OneTuple :: a -> OneTuple a
- Data.Tuple.OneTuple: data OneTuple a
- Data.Tuple.OneTuple: instance Control.Monad.Fix.MonadFix Data.Tuple.OneTuple.OneTuple
- Data.Tuple.OneTuple: instance Data.Foldable.Foldable Data.Tuple.OneTuple.OneTuple
- Data.Tuple.OneTuple: instance Data.Traversable.Traversable Data.Tuple.OneTuple.OneTuple
- Data.Tuple.OneTuple: instance GHC.Arr.Ix a => GHC.Arr.Ix (Data.Tuple.OneTuple.OneTuple a)
- Data.Tuple.OneTuple: instance GHC.Base.Applicative Data.Tuple.OneTuple.OneTuple
- Data.Tuple.OneTuple: instance GHC.Base.Functor Data.Tuple.OneTuple.OneTuple
- Data.Tuple.OneTuple: instance GHC.Base.Monad Data.Tuple.OneTuple.OneTuple
- Data.Tuple.OneTuple: instance GHC.Base.Monoid a => GHC.Base.Monoid (Data.Tuple.OneTuple.OneTuple a)
- Data.Tuple.OneTuple: instance GHC.Base.Semigroup a => GHC.Base.Semigroup (Data.Tuple.OneTuple.OneTuple a)
- Data.Tuple.OneTuple: instance GHC.Classes.Eq a => GHC.Classes.Eq (Data.Tuple.OneTuple.OneTuple a)
- Data.Tuple.OneTuple: instance GHC.Classes.Ord a => GHC.Classes.Ord (Data.Tuple.OneTuple.OneTuple a)
- Data.Tuple.OneTuple: instance GHC.Enum.Bounded a => GHC.Enum.Bounded (Data.Tuple.OneTuple.OneTuple a)
- Data.Tuple.OneTuple: instance GHC.Enum.Enum a => GHC.Enum.Enum (Data.Tuple.OneTuple.OneTuple a)
- Data.Tuple.OneTuple: instance GHC.Read.Read a => GHC.Read.Read (Data.Tuple.OneTuple.OneTuple a)
- Data.Tuple.OneTuple: instance GHC.Show.Show a => GHC.Show.Show (Data.Tuple.OneTuple.OneTuple a)
+ Data.Tuple.OneTuple: pattern OneTuple :: a -> Solo a
+ Data.Tuple.OneTuple: type OneTuple = Solo
+ Data.Tuple.Solo: Solo :: a -> Solo a
+ Data.Tuple.Solo: data Solo a
+ Data.Tuple.Solo: getSolo :: Solo a -> a
+ Data.Tuple.Solo: instance Control.Monad.Fix.MonadFix Data.Tuple.Solo.Solo
+ Data.Tuple.Solo: instance Control.Monad.Zip.MonadZip Data.Tuple.Solo.Solo
+ Data.Tuple.Solo: instance Data.Data.Data a => Data.Data.Data (Data.Tuple.Solo.Solo a)
+ Data.Tuple.Solo: instance Data.Foldable.Foldable Data.Tuple.Solo.Solo
+ Data.Tuple.Solo: instance Data.Functor.Classes.Eq1 Data.Tuple.Solo.Solo
+ Data.Tuple.Solo: instance Data.Functor.Classes.Ord1 Data.Tuple.Solo.Solo
+ Data.Tuple.Solo: instance Data.Functor.Classes.Read1 Data.Tuple.Solo.Solo
+ Data.Tuple.Solo: instance Data.Functor.Classes.Show1 Data.Tuple.Solo.Solo
+ Data.Tuple.Solo: instance Data.Traversable.Traversable Data.Tuple.Solo.Solo
+ Data.Tuple.Solo: instance GHC.Base.Applicative Data.Tuple.Solo.Solo
+ Data.Tuple.Solo: instance GHC.Base.Functor Data.Tuple.Solo.Solo
+ Data.Tuple.Solo: instance GHC.Base.Monad Data.Tuple.Solo.Solo
+ Data.Tuple.Solo: instance GHC.Base.Monoid a => GHC.Base.Monoid (Data.Tuple.Solo.Solo a)
+ Data.Tuple.Solo: instance GHC.Base.Semigroup a => GHC.Base.Semigroup (Data.Tuple.Solo.Solo a)
+ Data.Tuple.Solo: instance GHC.Classes.Eq a => GHC.Classes.Eq (Data.Tuple.Solo.Solo a)
+ Data.Tuple.Solo: instance GHC.Classes.Ord a => GHC.Classes.Ord (Data.Tuple.Solo.Solo a)
+ Data.Tuple.Solo: instance GHC.Enum.Bounded a => GHC.Enum.Bounded (Data.Tuple.Solo.Solo a)
+ Data.Tuple.Solo: instance GHC.Enum.Enum a => GHC.Enum.Enum (Data.Tuple.Solo.Solo a)
+ Data.Tuple.Solo: instance GHC.Generics.Generic (Data.Tuple.Solo.Solo a)
+ Data.Tuple.Solo: instance GHC.Generics.Generic1 Data.Tuple.Solo.Solo
+ Data.Tuple.Solo: instance GHC.Ix.Ix a => GHC.Ix.Ix (Data.Tuple.Solo.Solo a)
+ Data.Tuple.Solo: instance GHC.Read.Read a => GHC.Read.Read (Data.Tuple.Solo.Solo a)
+ Data.Tuple.Solo: instance GHC.Show.Show a => GHC.Show.Show (Data.Tuple.Solo.Solo a)
Files
- Changelog.md +7/−1
- OneTuple.cabal +48/−8
- src/Data/Tuple/OneTuple.hs +26/−80
- src/Data/Tuple/Solo.hs +208/−0
- test/instances.hs +60/−0
Changelog.md view
@@ -1,4 +1,10 @@-# next+# 0.3++- Rename `OneTuple` to `Solo`+- Add `Typeable`, `Data`, `MonadZip`, `Eq1`, `Ord1`, `Show1`, `Read1`,+ `Generic` and `Generic1` instances++# 0.2.2.1 - Compatible with GHC-8.6
OneTuple.cabal view
@@ -1,14 +1,16 @@ cabal-version: >=1.10 name: OneTuple-version: 0.2.2.1+version: 0.3 synopsis: Singleton Tuple category: Data description:- This package provides a singleton tuple data type+ This package is a compatibility package for a singleton data type .- > data OneTuple a = OneTuple a+ > data Solo a = Solo a . Note: it's not a @newtype@+ .+ @Solo@ is available in @base-4.16@ (GHC-9.2). copyright: (c) John Dorsey 2008 license: BSD3@@ -30,8 +32,10 @@ || ==8.2.2 || ==8.4.4 || ==8.6.5- || ==8.8.3- || ==8.10.1+ || ==8.8.4+ || ==8.10.4+ || ==9.0.1+ || ==9.2.1 extra-source-files: Changelog.md @@ -41,9 +45,45 @@ library default-language: Haskell98- exposed-modules: Data.Tuple.OneTuple+ exposed-modules:+ Data.Tuple.OneTuple+ Data.Tuple.Solo+ hs-source-dirs: src- build-depends: base >=4.3 && <4.15+ build-depends: base >=4.3 && <4.17 + if impl(ghc >=9.0)+ build-depends: ghc-prim+ if !impl(ghc >=8.0)- build-depends: semigroups >=0.18.4 && <0.20+ build-depends:+ semigroups >=0.18.4 && <0.20+ , transformers >=0.3 && <0.7++ -- Ensure Data.Functor.Classes is always available+ if impl(ghc >=7.10)+ build-depends: transformers >=0.4.2.0++ else+ build-depends: transformers-compat >=0.5.1.0 && <0.7++ if !impl(ghc >=9.2)+ build-depends: base-orphans >=0.8.6++ if !impl(ghc >=7.6)+ build-depends: ghc-prim++test-suite instances+ type: exitcode-stdio-1.0+ default-language: Haskell98+ hs-source-dirs: test+ main-is: instances.hs+ build-depends:+ base+ , OneTuple++ if !impl(ghc >=8.0)+ build-depends:+ semigroups+ , transformers+ , transformers-compat
src/Data/Tuple/OneTuple.hs view
@@ -1,85 +1,31 @@--- |OneTuple fills the /tuple gap/ with a singleton tuple.------ OneTuple /does not support/ the usual parenthesized tuple syntax.------ OneTuple------ * has the expected laziness properties------ * can be pattern-matched------ * ships with instances for several standard type classes,--- including all those supported by H98-standard tuples+{-# LANGUAGE CPP #-}+#if __GLASGOW_HASKELL__ >= 708+{-# LANGUAGE PatternSynonyms #-}+#endif+-- | This is a module to help migration from @OneTuple@ to @Solo@.+-- Migrate to use "Data.Tuple" from @base-4.16@ or "Data.Tuple.Solo" with all GHCs. ----- * requires no language extensions, except for hierarchical modules--module Data.Tuple.OneTuple (OneTuple(OneTuple), only) where--import Control.Applicative (Applicative (..))-import Control.Monad (ap)-import Control.Monad.Fix (MonadFix (..))-import Data.Foldable (Foldable (..))-import Data.Ix (Ix (..))-import Data.Monoid (Monoid (..))-import Data.Semigroup (Semigroup (..))-import Data.Traversable (Traversable (..))---- |OneTuple is the singleton tuple data type.-data OneTuple a- = OneTuple a -- ^ singleton tuple constructor- deriving (Eq,Ord,Bounded,Show,Read)---- |The 'only' function extracts the OneTuple's only member.--- (Compare to 'fst' and 'snd'.)-only :: OneTuple a -- ^ takes a singleton tuple argument- -> a -- ^ returns the only element in the tuple-only (OneTuple x) = x--instance (Enum a) => Enum (OneTuple a) where- succ = fmap succ- pred = fmap pred- toEnum = pure . toEnum- fromEnum (OneTuple x) = fromEnum x--instance (Ix a) => Ix (OneTuple a) where- range (OneTuple x, OneTuple y) = map OneTuple (range (x,y))- index (OneTuple x, OneTuple y) (OneTuple z) = index (x,y) z- inRange (OneTuple x, OneTuple y) (OneTuple z) = inRange (x,y) z--instance Foldable OneTuple where- fold (OneTuple m) = m- foldMap f (OneTuple x) = f x- foldr f b (OneTuple x) = f x b- foldl f a (OneTuple x) = f a x- foldr1 _f (OneTuple x) = x- foldl1 _f (OneTuple x) = x--instance Traversable OneTuple where- traverse f (OneTuple x) = fmap OneTuple (f x)- sequenceA (OneTuple x) = fmap OneTuple x--instance Functor OneTuple where- fmap f (OneTuple x) = OneTuple (f x)--instance Applicative OneTuple where- pure = OneTuple-- OneTuple f <*> OneTuple x = OneTuple (f x)- _ *> x = x- x <* _ = x--instance Monad OneTuple where- return = pure- (>>) = (*>)- (OneTuple x) >>= f = f x+-- The pattern synonym is provided for GHCs supporting pattern synonyms (7.8+)+module Data.Tuple.OneTuple+{-# DEPRECATED "Use Data.Tuple.Solo" #-}+(+ OneTuple,+#if __GLASGOW_HASKELL__ >= 708+ pattern OneTuple,+#endif+ only,+) where -instance (Semigroup a) => Semigroup (OneTuple a) where- OneTuple x <> OneTuple y = OneTuple (x <> y)+import Data.Tuple.Solo -instance (Monoid a) => Monoid (OneTuple a) where- mempty = OneTuple mempty- mappend (OneTuple x) (OneTuple y) = OneTuple (mappend x y)+type OneTuple = Solo -instance MonadFix OneTuple where- mfix f = let a = f (only a) in a+only :: OneTuple a -> a+only = getSolo +#if __GLASGOW_HASKELL__ >= 708+#if __GLASGOW_HASKELL__ >= 710+pattern OneTuple :: a -> Solo a+#endif+pattern OneTuple a = Solo a+#endif
+ src/Data/Tuple/Solo.hs view
@@ -0,0 +1,208 @@+{-# LANGUAGE CPP #-}+{-# LANGUAGE DeriveDataTypeable #-}+#if __GLASGOW_HASKELL__ >= 704+{-# LANGUAGE Safe #-}+#elif __GLASGOW_HASKELL__ >= 702+{-# LANGUAGE Trustworthy #-}+#endif+#if __GLASGOW_HASKELL__ >=702+{-# LANGUAGE DeriveGeneric #-}+#endif++-- | 'Solo' fills the /tuple gap/ with a singleton tuple.+--+-- 'Solo' /does not support/ the usual parenthesized tuple syntax.+--+-- 'Solo'+--+-- * has the expected laziness properties+--+-- * can be pattern-matched+--+-- * ships with instances for several standard type classes,+-- including all those supported by H98-standard tuples+--+-- * requires no language extensions, except for hierarchical modules+--+-- Note: on GHC-9.0 'getSolo' is not a record selector.++module Data.Tuple.Solo (+ Solo(Solo),+ getSolo,+) where++#ifdef MIN_VERSION_base_orphans+import Data.Orphans ()+#endif++#if MIN_VERSION_base(4,16,0)+import GHC.Tuple (Solo (Solo), getSolo)++#elif MIN_VERSION_base(4,15,0)+import GHC.Tuple (Solo (Solo))++-- | The 'getSolo' function extracts the Solo's getSolo member.+getSolo :: Solo a -> a+getSolo (Solo x) = x++#else++#if MIN_VERSION_base(4,9,0)+#define LIFTED_FUNCTOR_CLASSES 1+#else+#if MIN_VERSION_transformers(0,5,0)+#define LIFTED_FUNCTOR_CLASSES 1+#else+#ifdef MIN_VERSION_transformers_compat+#if MIN_VERSION_transformers_compat(0,5,0) && !(MIN_VERSION_transformers(0,4,0))+#define LIFTED_FUNCTOR_CLASSES 1+#endif+#endif+#endif+#endif++import Control.Applicative (Applicative (..))+import Control.Monad (ap)+import Control.Monad.Fix (MonadFix (..))+import Data.Data (Data)+import Data.Foldable (Foldable (..))+import Data.Ix (Ix (..))+import Data.Monoid (Monoid (..))+import Data.Semigroup (Semigroup (..))+import Data.Traversable (Traversable (..))+import Data.Typeable (Typeable)++import Data.Functor.Classes (Eq1 (..), Ord1 (..), Show1 (..), Read1 (..))++#if LIFTED_FUNCTOR_CLASSES+#if MIN_VERSION_base(4,10,0)+import Data.Functor.Classes (readData, readUnaryWith, liftReadListDefault, liftReadListPrecDefault)+#else+import Data.Functor.Classes (readsData, readsUnaryWith)+#endif+#endif++#if MIN_VERSION_base(4,4,0)+import GHC.Generics (Generic, Generic1)+#endif++#if MIN_VERSION_base(4,4,0)+import Control.Monad.Zip (MonadZip (..))+#endif++-- | Solo is the singleton tuple data type.+data Solo a = Solo { getSolo :: a }+ deriving+ ( Eq,Ord,Bounded,Read,Typeable,Data+#if MIN_VERSION_base(4,4,0)+ , Generic+#if __GLASGOW_HASKELL__ >=706+ , Generic1+#endif+#endif+ )++instance Show a => Show (Solo a) where+ showsPrec d (Solo x) = showParen (d > 10) $+ showString "Solo " . showsPrec 11 x++instance (Enum a) => Enum (Solo a) where+ succ = fmap succ+ pred = fmap pred+ toEnum = pure . toEnum+ fromEnum (Solo x) = fromEnum x++instance (Ix a) => Ix (Solo a) where+ range (Solo x, Solo y) = map Solo (range (x,y))+ index (Solo x, Solo y) (Solo z) = index (x,y) z+ inRange (Solo x, Solo y) (Solo z) = inRange (x,y) z++instance Foldable Solo where+ fold (Solo m) = m+ foldMap f (Solo x) = f x+ foldr f b (Solo x) = f x b+ foldl f a (Solo x) = f a x+ foldr1 _f (Solo x) = x+ foldl1 _f (Solo x) = x++ -- TODO: add rest of the methods+#if MIN_VERSION_base(4,8,0)+ null _ = False+ length _ = 1++ maximum = getSolo+ minimum = getSolo+ sum = getSolo+ product = getSolo++ toList (Solo a) = [a]+#endif++instance Traversable Solo where+ traverse f (Solo x) = fmap Solo (f x)+ sequenceA (Solo x) = fmap Solo x+++instance Functor Solo where+ fmap f (Solo x) = Solo (f x)++instance Applicative Solo where+ pure = Solo++ Solo f <*> Solo x = Solo (f x)+ _ *> x = x+ x <* _ = x++#if MIN_VERSION_base(4,10,0)+ liftA2 f (Solo x) (Solo y) = Solo (f x y)+#endif++instance Monad Solo where+ return = pure+ (>>) = (*>)+ Solo x >>= f = f x++instance Semigroup a => Semigroup (Solo a) where+ Solo x <> Solo y = Solo (x <> y)++instance Monoid a => Monoid (Solo a) where+ mempty = Solo mempty+ mappend (Solo x) (Solo y) = Solo (mappend x y)++instance MonadFix Solo where+ mfix f = let a = f (getSolo a) in a++#if MIN_VERSION_base(4,4,0)+instance MonadZip Solo where+ mzipWith f (Solo a) (Solo b) = Solo (f a b)+#endif++#ifdef LIFTED_FUNCTOR_CLASSES+instance Eq1 Solo where+ liftEq eq (Solo a) (Solo b) = a `eq` b++instance Ord1 Solo where+ liftCompare cmp (Solo a) (Solo b) = cmp a b++instance Read1 Solo where+#if MIN_VERSION_base(4,10,0)+ liftReadPrec rp _ = readData (readUnaryWith rp "Solo" Solo)++ liftReadListPrec = liftReadListPrecDefault+ liftReadList = liftReadListDefault+#else+ liftReadsPrec rp _ = readsData $ readsUnaryWith rp "Solo" Solo+#endif++instance Show1 Solo where+ liftShowsPrec sp _ d (Solo x) = showParen (d > 10) $+ showString "Solo " . sp 11 x++#else+instance Eq1 Solo where eq1 = (==)+instance Ord1 Solo where compare1 = compare+instance Read1 Solo where readsPrec1 = readsPrec+instance Show1 Solo where showsPrec1 = showsPrec+#endif++#endif
+ test/instances.hs view
@@ -0,0 +1,60 @@+{-# LANGUAGE CPP #-}+module Main where++import Control.Applicative (Applicative (..))+import Control.Monad.Fix (MonadFix (..))+import Data.Data (Data)+import Data.Foldable (Foldable (..))+import Data.Functor.Classes (Eq1, Ord1, Read1, Show1)+import Data.Ix (Ix)+import Data.Monoid (Monoid (..))+import Data.Semigroup (Semigroup (..))+import Data.Traversable (Traversable (..))++#if MIN_VERSION_base(4,4,0)+import Control.Monad.Zip (MonadZip (..))+#endif++import Data.Tuple.Solo (Solo (..))++main :: IO ()+main = putStrLn "works"++-------------------------------------------------------------------------------+-- Instances+-------------------------------------------------------------------------------++tup1 :: Solo Char+tup1 = Solo 'x'++tup2 :: Solo String+tup2 = Solo "test"++hasEq :: Eq a => a -> a; hasEq x = x; testEq = hasEq tup1+hasOrd :: Ord a => a -> a; hasOrd x = x; testOrd = hasOrd tup1+hasBounded :: Bounded a => a -> a; hasBounded x = x; testBounded = hasBounded tup1+hasEnum :: Enum a => a -> a; hasEnum x = x; testEnum = hasEnum tup1+hasShow :: Show a => a -> a; hasShow x = x; testShow = hasShow tup1+hasRead :: Read a => a -> a; hasRead x = x; testRead = hasRead tup1+hasIx :: Ix a => a -> a; hasIx x = x; testIx = hasIx tup1++hasMonoid :: Monoid a => a -> a; hasMonoid x = x; testMonoid = hasMonoid tup2+hasSemigroup :: Semigroup a => a -> a; hasSemigroup x = x; testSemigroup = hasSemigroup tup2++hasData :: Data a => a -> a; hasData x = x; testData = hasData tup2++hasFunctor :: Functor f => f a -> f a; hasFunctor x = x; testFunctor = hasFunctor tup1+hasFoldable :: Foldable f => f a -> f a; hasFoldable x = x; testFoldable = hasFoldable tup1+hasTraversable :: Traversable f => f a -> f a; hasTraversable x = x; testTraversable = hasTraversable tup1+hasApplicative :: Applicative f => f a -> f a; hasApplicative x = x; testApplicative = hasApplicative tup1+hasMonad :: Monad f => f a -> f a; hasMonad x = x; testMonad = hasMonad tup1+hasMonadFix :: MonadFix f => f a -> f a; hasMonadFix x = x; testMonadFix = hasMonadFix tup1++#if MIN_VERSION_base(4,4,0)+hasMonadZip :: MonadZip f => f a -> f a; hasMonadZip x = x; testMonadZip = hasMonadZip tup1+#endif++hasEq1 :: Eq1 f => f a -> f a; hasEq1 x = x; testEq1 = hasEq1 tup1+hasOrd1 :: Ord1 f => f a -> f a; hasOrd1 x = x; testOrd1 = hasOrd1 tup1+hasShow1 :: Show1 f => f a -> f a; hasShow1 x = x; testShow1 = hasShow1 tup1+hasRead1 :: Read1 f => f a -> f a; hasRead1 x = x; testRead1 = hasRead1 tup1