OneTuple-0.4.1.1/0000755000000000000000000000000007346545000011577 5ustar0000000000000000OneTuple-0.4.1.1/Changelog.md0000644000000000000000000000120507346545000014006 0ustar0000000000000000# 0.4.1.1 - Support GHC-7.2 and GHC-7.0. # 0.4.1 - Mark `MkSolo` pattern synonym as `COMPLETE` # 0.4 - Rename constructor to `MkSolo` as in `base-4.17`. The compatibility pattern synonym is provided. - Add `Foldable1 Solo` instance # 0.3.1 - Add `Data.Tuple.Solo.TH` with `tupE` using `Solo` from this package - Add `Hashable` and `Hashable1` instances - Drop GHC-7.0 and GHC-7.2 support # 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 # 0.2.2 - Add `Semigroup` instances - Compatible with GHC-8.4 OneTuple-0.4.1.1/LICENSE0000644000000000000000000000274407346545000012613 0ustar0000000000000000 Copyright (c) 2008, John A. Dorsey. All rights reserved. Redistribution and use of this software 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 John Dorsey nor the names of its 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. OneTuple-0.4.1.1/OneTuple.cabal0000644000000000000000000000475307346545000014327 0ustar0000000000000000cabal-version: 1.12 name: OneTuple version: 0.4.1.1 synopsis: Singleton Tuple category: Data description: This package is a compatibility package for a singleton data type . > data Solo a = MkSolo a . Note: it's not a @newtype@ . @Solo@ is available in @base-4.16@ (GHC-9.2). copyright: (c) John Dorsey 2008 license: BSD3 license-file: LICENSE author: John Dorsey maintainer: Oleg Grenrus , John Dorsey stability: experimental build-type: Simple tested-with: GHC ==7.0.4 || ==7.2.2 || ==7.4.2 || ==7.6.3 || ==7.8.4 || ==7.10.3 || ==8.0.2 || ==8.2.2 || ==8.4.4 || ==8.6.5 || ==8.8.4 || ==8.10.7 || ==9.0.2 || ==9.2.5 || ==9.4.4 || ==9.6.1 extra-source-files: Changelog.md source-repository head type: git location: https://github.com/phadej/OneTuple.git library default-language: Haskell98 exposed-modules: Data.Tuple.OneTuple Data.Tuple.Solo Data.Tuple.Solo.TH hs-source-dirs: src build-depends: base >=4.3 && <4.19 , template-haskell if impl(ghc >=9.0) build-depends: ghc-prim else if impl(ghc >=7.4) build-depends: hashable >=1.3.5.0 && <1.5 else build-depends: hashable >=1.2.5.0 && <1.3 -- generics if !impl(ghc >=7.6) build-depends: ghc-prim if !impl(ghc >=8.0) build-depends: semigroups >=0.18.4 && <0.21 , 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.8 if !impl(ghc >=9.0) build-depends: foldable1-classes-compat >=0.1 && <0.2 if !impl(ghc >=9.2) build-depends: base-orphans >=0.8.6 test-suite instances type: exitcode-stdio-1.0 default-language: Haskell98 hs-source-dirs: test main-is: instances.hs build-depends: base , hashable , OneTuple if !impl(ghc >=8.0) build-depends: semigroups , transformers , transformers-compat if !impl(ghc >=9.6) build-depends: foldable1-classes-compat >=0.1 && <0.2 test-suite th type: exitcode-stdio-1.0 default-language: Haskell98 hs-source-dirs: test main-is: th.hs build-depends: base , OneTuple , template-haskell OneTuple-0.4.1.1/Setup.hs0000644000000000000000000000006107346545000013230 0ustar0000000000000000 import Distribution.Simple main = defaultMain OneTuple-0.4.1.1/src/Data/Tuple/0000755000000000000000000000000007346545000014330 5ustar0000000000000000OneTuple-0.4.1.1/src/Data/Tuple/OneTuple.hs0000644000000000000000000000142507346545000016421 0ustar0000000000000000{-# 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. -- -- 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 import Data.Tuple.Solo type OneTuple = Solo only :: OneTuple a -> a only = getSolo #if __GLASGOW_HASKELL__ >= 708 #if __GLASGOW_HASKELL__ >= 710 pattern OneTuple :: a -> Solo a #endif pattern OneTuple a = MkSolo a #endif #if __GLASGOW_HASKELL__ >= 800 {-# COMPLETE OneTuple #-} #endif OneTuple-0.4.1.1/src/Data/Tuple/Solo.hs0000644000000000000000000001447607346545000015614 0ustar0000000000000000{-# LANGUAGE CPP #-} {-# LANGUAGE DeriveDataTypeable #-} #if __GLASGOW_HASKELL__ >=702 {-# LANGUAGE DeriveGeneric #-} #endif #if __GLASGOW_HASKELL__ >= 708 {-# LANGUAGE PatternSynonyms #-} #endif #if __GLASGOW_HASKELL__ >=704 {-# LANGUAGE Safe #-} #elif __GLASGOW_HASKELL__ >=702 {-# LANGUAGE Trustworthy #-} #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 ( #if __GLASGOW_HASKELL__ >= 800 Solo(MkSolo,Solo), #elif __GLASGOW_HASKELL__ >= 708 Solo(MkSolo), pattern Solo, #else Solo(MkSolo), #endif getSolo, ) where #ifdef MIN_VERSION_base_orphans import Data.Orphans () #endif #if MIN_VERSION_base(4,18,0) import GHC.Tuple (Solo (MkSolo, Solo), getSolo) #elif MIN_VERSION_base(4,16,0) import GHC.Tuple (Solo (Solo), getSolo) pattern MkSolo :: a -> Solo a pattern MkSolo a = Solo a {-# COMPLETE MkSolo #-} #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 pattern MkSolo :: a -> Solo a pattern MkSolo a = Solo a {-# COMPLETE MkSolo #-} #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.List.NonEmpty (NonEmpty (..)) import Data.Monoid (Monoid (..)) import Data.Semigroup (Semigroup (..)) import Data.Traversable (Traversable (..)) import Data.Typeable (Typeable) import qualified Data.Foldable1 as F1 import Data.Functor.Classes (Eq1 (..), Ord1 (..), Show1 (..), Read1 (..)) #if !(MIN_VERSION_base(4,15,0)) import Data.Hashable (Hashable (..)) import Data.Hashable.Lifted (Hashable1 (..), hashWithSalt1) #endif #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) import Control.Monad.Zip (MonadZip (..)) #endif -- | Solo is the singleton tuple data type. data Solo a = MkSolo { getSolo :: a } deriving ( Eq,Ord,Bounded,Read,Typeable,Data #if MIN_VERSION_base(4,4,0) , Generic #if __GLASGOW_HASKELL__ >=706 , Generic1 #endif #endif ) #if __GLASGOW_HASKELL__ >= 708 #if __GLASGOW_HASKELL__ >= 710 pattern Solo :: a -> Solo a #endif pattern Solo a = MkSolo a #endif #if __GLASGOW_HASKELL__ >= 800 {-# COMPLETE Solo #-} #endif instance Show a => Show (Solo a) where showsPrec d (MkSolo x) = showParen (d > 10) $ showString "MkSolo " . showsPrec 11 x instance (Enum a) => Enum (Solo a) where succ = fmap succ pred = fmap pred toEnum = pure . toEnum fromEnum (MkSolo x) = fromEnum x instance (Ix a) => Ix (Solo a) where range (MkSolo x, MkSolo y) = map MkSolo (range (x,y)) index (MkSolo x, MkSolo y) (MkSolo z) = index (x,y) z inRange (MkSolo x, MkSolo y) (MkSolo z) = inRange (x,y) z instance Foldable Solo where fold (MkSolo m) = m foldMap f (MkSolo x) = f x foldr f b (MkSolo x) = f x b foldl f a (MkSolo x) = f a x foldr1 _f (MkSolo x) = x foldl1 _f (MkSolo 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 (MkSolo a) = [a] #endif -- | @since 0.4 instance F1.Foldable1 Solo where foldMap1 f (MkSolo y) = f y toNonEmpty (MkSolo x) = x :| [] minimum (MkSolo x) = x maximum (MkSolo x) = x head (MkSolo x) = x last (MkSolo x) = x instance Traversable Solo where traverse f (MkSolo x) = fmap MkSolo (f x) sequenceA (MkSolo x) = fmap MkSolo x instance Functor Solo where fmap f (MkSolo x) = MkSolo (f x) instance Applicative Solo where pure = MkSolo MkSolo f <*> MkSolo x = MkSolo (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 (>>) = (*>) MkSolo x >>= f = f x instance Semigroup a => Semigroup (Solo a) where MkSolo x <> MkSolo y = MkSolo (x <> y) instance Monoid a => Monoid (Solo a) where mempty = MkSolo mempty mappend (MkSolo x) (MkSolo y) = MkSolo (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 (MkSolo a) (MkSolo b) = MkSolo (f a b) #endif #ifdef LIFTED_FUNCTOR_CLASSES instance Eq1 Solo where liftEq eq (MkSolo a) (MkSolo b) = a `eq` b instance Ord1 Solo where liftCompare cmp (MkSolo a) (MkSolo b) = cmp a b instance Read1 Solo where #if MIN_VERSION_base(4,10,0) liftReadPrec rp _ = readData (readUnaryWith rp "MkSolo" MkSolo) liftReadListPrec = liftReadListPrecDefault liftReadList = liftReadListDefault #else liftReadsPrec rp _ = readsData $ readsUnaryWith rp "MkSolo" MkSolo #endif instance Show1 Solo where liftShowsPrec sp _ d (MkSolo x) = showParen (d > 10) $ showString "MkSolo " . 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 #if !(MIN_VERSION_base(4,15,0)) -- | @since 0.3.1 instance Hashable a => Hashable (Solo a) where hashWithSalt = hashWithSalt1 -- | @since 0.3.1 instance Hashable1 Solo where liftHashWithSalt h salt (MkSolo a) = h salt a #endif OneTuple-0.4.1.1/src/Data/Tuple/Solo/0000755000000000000000000000000007346545000015244 5ustar0000000000000000OneTuple-0.4.1.1/src/Data/Tuple/Solo/TH.hs0000644000000000000000000000172107346545000016114 0ustar0000000000000000{-# LANGUAGE CPP #-} #if __GLASGOW_HASKELL__ >= 800 {-# LANGUAGE TemplateHaskellQuotes #-} #endif -- | This module provides TH helpers, -- which use 'Solo' from this package, for 1-tuples. module Data.Tuple.Solo.TH ( tupE, ) where #if MIN_VERSION_template_haskell(2,17,0) import Language.Haskell.TH (tupE) #else import Data.Tuple.Solo import qualified Language.Haskell.TH as TH import qualified Language.Haskell.TH.Syntax as TH makeTup :: [TH.Exp] -> TH.Exp makeTup [x] = TH.AppE (TH.ConE soloConName) x #if MIN_VERSION_template_haskell(2,16,0) makeTup xs = TH.TupE (map Just xs) #else makeTup xs = TH.TupE xs #endif soloConName :: TH.Name #if __GLASGOW_HASKELL__ >= 800 soloConName = 'Solo #else #ifndef CURRENT_PACKAGE_KEY #error "CURRENT_PACKAGE_KEY undefined" #endif soloConName = TH.mkNameG_d CURRENT_PACKAGE_KEY "Data.Tuple.Solo" "MkSolo" #endif tupE :: Monad m => [m TH.Exp] -> m TH.Exp tupE xs = do xs' <- sequence xs return (makeTup xs') #endif OneTuple-0.4.1.1/test/0000755000000000000000000000000007346545000012556 5ustar0000000000000000OneTuple-0.4.1.1/test/instances.hs0000644000000000000000000000637107346545000015110 0ustar0000000000000000{-# LANGUAGE CPP #-} #if __GLASGOW_HASKELL__ >= 800 {-# OPTIONS_GHC -Wincomplete-patterns -Werror=incomplete-patterns #-} #else {-# OPTIONS_GHC -fwarn-incomplete-patterns -Werror #-} #endif module Main where import Control.Applicative (Applicative (..)) import Control.Monad.Fix (MonadFix (..)) import Data.Data (Data) import Data.Foldable (Foldable (..)) import Data.Foldable1 (Foldable1) import Data.Functor.Classes (Eq1, Ord1, Read1, Show1) import Data.Hashable (Hashable) import Data.Hashable.Lifted (Hashable1) 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" ------------------------------------------------------------------------------- -- pattern match ------------------------------------------------------------------------------- match :: Solo a -> a match (MkSolo x) = x ------------------------------------------------------------------------------- -- Instances ------------------------------------------------------------------------------- tup1 :: Solo Char tup1 = MkSolo 'x' tup2 :: Solo String tup2 = MkSolo "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 hasFoldable1 :: Foldable1 f => f a -> f a; hasFoldable1 x = x; testFoldable1 = hasFoldable1 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 hasHashable :: Hashable a => a -> a; hasHashable x = x; testHashable = hasHashable tup1 hasHashable1 :: Hashable1 f => f a -> f a; hasHashable1 x = x; testHashable1 = hasHashable1 tup1 OneTuple-0.4.1.1/test/th.hs0000644000000000000000000000025407346545000013526 0ustar0000000000000000{-# LANGUAGE TemplateHaskell #-} module Main where import Data.Tuple.Solo import Data.Tuple.Solo.TH (tupE) main :: IO () main = print $ MkSolo 'x' == $(tupE [[| 'x' |]])