|
Packit |
9a2dfb |
{-# LANGUAGE CPP #-}
|
|
Packit |
9a2dfb |
{-# LANGUAGE DeriveDataTypeable #-}
|
|
Packit |
9a2dfb |
{-# LANGUAGE DeriveGeneric #-}
|
|
Packit |
9a2dfb |
{-# LANGUAGE FlexibleInstances #-}
|
|
Packit |
9a2dfb |
{-# LANGUAGE GADTs #-}
|
|
Packit |
9a2dfb |
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
|
|
Packit |
9a2dfb |
{-# LANGUAGE StandaloneDeriving #-}
|
|
Packit |
9a2dfb |
{-# LANGUAGE ScopedTypeVariables #-}
|
|
Packit |
9a2dfb |
|
|
Packit |
9a2dfb |
module Types (module Types) where
|
|
Packit |
9a2dfb |
|
|
Packit |
9a2dfb |
import Prelude ()
|
|
Packit |
9a2dfb |
import Prelude.Compat
|
|
Packit |
9a2dfb |
|
|
Packit |
9a2dfb |
import Math.NumberTheory.Logarithms (intLog2)
|
|
Packit |
9a2dfb |
import Data.Data
|
|
Packit |
9a2dfb |
import Data.Functor.Compose (Compose (..))
|
|
Packit |
9a2dfb |
import Data.Functor.Identity (Identity (..))
|
|
Packit |
9a2dfb |
import Data.Hashable (Hashable (..))
|
|
Packit |
9a2dfb |
import Data.Semigroup (Option)
|
|
Packit |
9a2dfb |
import Data.Text
|
|
Packit |
9a2dfb |
import Data.Time (Day (..), fromGregorian)
|
|
Packit |
9a2dfb |
import GHC.Generics
|
|
Packit |
9a2dfb |
import Test.QuickCheck (Arbitrary (..), Property, counterexample, scale)
|
|
Packit |
9a2dfb |
import qualified Data.Map as Map
|
|
Packit |
9a2dfb |
import Data.Aeson
|
|
Packit |
9a2dfb |
import Data.Aeson.Types
|
|
Packit |
9a2dfb |
|
|
Packit |
9a2dfb |
type I = Identity
|
|
Packit |
9a2dfb |
type Compose3 f g h = Compose (Compose f g) h
|
|
Packit |
9a2dfb |
type Compose3' f g h = Compose f (Compose g h)
|
|
Packit |
9a2dfb |
|
|
Packit |
9a2dfb |
data Foo = Foo {
|
|
Packit |
9a2dfb |
fooInt :: Int
|
|
Packit |
9a2dfb |
, fooDouble :: Double
|
|
Packit |
9a2dfb |
, fooTuple :: (String, Text, Int)
|
|
Packit |
9a2dfb |
-- This definition causes an infinite loop in genericTo and genericFrom!
|
|
Packit |
9a2dfb |
-- , fooMap :: Map.Map String Foo
|
|
Packit |
9a2dfb |
, fooMap :: Map.Map String (Text,Int)
|
|
Packit |
9a2dfb |
} deriving (Show, Typeable, Data)
|
|
Packit |
9a2dfb |
|
|
Packit |
9a2dfb |
data UFoo = UFoo {
|
|
Packit |
9a2dfb |
_UFooInt :: Int
|
|
Packit |
9a2dfb |
, uFooInt :: Int
|
|
Packit |
9a2dfb |
} deriving (Show, Eq, Data, Typeable)
|
|
Packit |
9a2dfb |
|
|
Packit |
9a2dfb |
data OneConstructor = OneConstructor
|
|
Packit |
9a2dfb |
deriving (Show, Eq, Typeable, Data)
|
|
Packit |
9a2dfb |
|
|
Packit |
9a2dfb |
data Product2 a b = Product2 a b
|
|
Packit |
9a2dfb |
deriving (Show, Eq, Typeable, Data)
|
|
Packit |
9a2dfb |
|
|
Packit |
9a2dfb |
data Product6 a b c d e f = Product6 a b c d e f
|
|
Packit |
9a2dfb |
deriving (Show, Eq, Typeable, Data)
|
|
Packit |
9a2dfb |
|
|
Packit |
9a2dfb |
data Sum4 a b c d = Alt1 a | Alt2 b | Alt3 c | Alt4 d
|
|
Packit |
9a2dfb |
deriving (Show, Eq, Typeable, Data)
|
|
Packit |
9a2dfb |
|
|
Packit |
9a2dfb |
class ApproxEq a where
|
|
Packit |
9a2dfb |
(=~) :: a -> a -> Bool
|
|
Packit |
9a2dfb |
|
|
Packit |
9a2dfb |
newtype Approx a = Approx { fromApprox :: a }
|
|
Packit |
9a2dfb |
deriving (Show, Data, Typeable, ApproxEq, Num)
|
|
Packit |
9a2dfb |
|
|
Packit |
9a2dfb |
instance (ApproxEq a) => Eq (Approx a) where
|
|
Packit |
9a2dfb |
Approx a == Approx b = a =~ b
|
|
Packit |
9a2dfb |
|
|
Packit |
9a2dfb |
data Nullary = C1 | C2 | C3 deriving (Eq, Show)
|
|
Packit |
9a2dfb |
|
|
Packit |
9a2dfb |
data SomeType a = Nullary
|
|
Packit |
9a2dfb |
| Unary Int
|
|
Packit |
9a2dfb |
| Product String (Maybe Char) a
|
|
Packit |
9a2dfb |
| Record { testOne :: Double
|
|
Packit |
9a2dfb |
, testTwo :: Maybe Bool
|
|
Packit |
9a2dfb |
, testThree :: Maybe a
|
|
Packit |
9a2dfb |
}
|
|
Packit |
9a2dfb |
| List [a]
|
|
Packit |
9a2dfb |
deriving (Eq, Show)
|
|
Packit |
9a2dfb |
|
|
Packit |
9a2dfb |
-- | This type requires IncoherentInstances for the instances of the type
|
|
Packit |
9a2dfb |
-- classes Data.Aeson.TH.LookupField and Data.Aeson.Types.FromJSON.FromRecord.
|
|
Packit |
9a2dfb |
--
|
|
Packit |
9a2dfb |
-- The minimum known requirements for this type are:
|
|
Packit |
9a2dfb |
-- * Record type with at least two fields
|
|
Packit |
9a2dfb |
-- * One field type is either a type parameter or a type/data family
|
|
Packit |
9a2dfb |
-- * Another field type is a @Maybe@ of the above field type
|
|
Packit |
9a2dfb |
data IncoherentInstancesNeeded a = IncoherentInstancesNeeded
|
|
Packit |
9a2dfb |
{ incoherentInstancesNeededMaybeNot :: a
|
|
Packit |
9a2dfb |
, incoherentInstancesNeededMaybeYes :: Maybe a
|
|
Packit |
9a2dfb |
} deriving Generic
|
|
Packit |
9a2dfb |
|
|
Packit |
9a2dfb |
-- Used for testing UntaggedValue SumEncoding
|
|
Packit |
9a2dfb |
data EitherTextInt
|
|
Packit |
9a2dfb |
= LeftBool Bool
|
|
Packit |
9a2dfb |
| RightInt Int
|
|
Packit |
9a2dfb |
| BothTextInt Text Int
|
|
Packit |
9a2dfb |
| NoneNullary
|
|
Packit |
9a2dfb |
deriving (Eq, Show)
|
|
Packit |
9a2dfb |
|
|
Packit |
9a2dfb |
data GADT a where
|
|
Packit |
9a2dfb |
GADT :: { gadt :: String } -> GADT String
|
|
Packit |
9a2dfb |
deriving Typeable
|
|
Packit |
9a2dfb |
|
|
Packit |
9a2dfb |
deriving instance Data (GADT String)
|
|
Packit |
9a2dfb |
deriving instance Eq (GADT a)
|
|
Packit |
9a2dfb |
deriving instance Show (GADT a)
|
|
Packit |
9a2dfb |
|
|
Packit |
9a2dfb |
newtype MaybeField = MaybeField { maybeField :: Maybe Int }
|
|
Packit |
9a2dfb |
newtype OptionField = OptionField { optionField :: Option Int }
|
|
Packit |
9a2dfb |
deriving (Eq, Show)
|
|
Packit |
9a2dfb |
|
|
Packit |
9a2dfb |
deriving instance Generic Foo
|
|
Packit |
9a2dfb |
deriving instance Generic UFoo
|
|
Packit |
9a2dfb |
deriving instance Generic OneConstructor
|
|
Packit |
9a2dfb |
deriving instance Generic (Product2 a b)
|
|
Packit |
9a2dfb |
deriving instance Generic (Product6 a b c d e f)
|
|
Packit |
9a2dfb |
deriving instance Generic (Sum4 a b c d)
|
|
Packit |
9a2dfb |
deriving instance Generic (Approx a)
|
|
Packit |
9a2dfb |
deriving instance Generic Nullary
|
|
Packit |
9a2dfb |
deriving instance Generic (SomeType a)
|
|
Packit |
9a2dfb |
#if __GLASGOW_HASKELL__ >= 706
|
|
Packit |
9a2dfb |
deriving instance Generic1 SomeType
|
|
Packit |
9a2dfb |
#endif
|
|
Packit |
9a2dfb |
deriving instance Generic OptionField
|
|
Packit |
9a2dfb |
deriving instance Generic EitherTextInt
|
|
Packit |
9a2dfb |
|
|
Packit |
9a2dfb |
failure :: Show a => String -> String -> a -> Property
|
|
Packit |
9a2dfb |
failure func msg v = counterexample
|
|
Packit |
9a2dfb |
(func ++ " failed: " ++ msg ++ ", " ++ show v) False
|
|
Packit |
9a2dfb |
|
|
Packit |
9a2dfb |
newtype BCEDay = BCEDay Day
|
|
Packit |
9a2dfb |
deriving (Eq, Show)
|
|
Packit |
9a2dfb |
|
|
Packit |
9a2dfb |
zeroDay :: Day
|
|
Packit |
9a2dfb |
zeroDay = fromGregorian 0 0 0
|
|
Packit |
9a2dfb |
|
|
Packit |
9a2dfb |
instance Arbitrary BCEDay where
|
|
Packit |
9a2dfb |
arbitrary = fmap (BCEDay . ModifiedJulianDay . (+ toModifiedJulianDay zeroDay)) arbitrary
|
|
Packit |
9a2dfb |
|
|
Packit |
9a2dfb |
instance ToJSON BCEDay where
|
|
Packit |
9a2dfb |
toJSON (BCEDay d) = toJSON d
|
|
Packit |
9a2dfb |
toEncoding (BCEDay d) = toEncoding d
|
|
Packit |
9a2dfb |
|
|
Packit |
9a2dfb |
instance FromJSON BCEDay where
|
|
Packit |
9a2dfb |
parseJSON = fmap BCEDay . parseJSON
|
|
Packit |
9a2dfb |
|
|
Packit |
9a2dfb |
-- | Scale the size of Arbitrary with ''
|
|
Packit |
9a2dfb |
newtype LogScaled a = LogScaled { getLogScaled :: a }
|
|
Packit |
9a2dfb |
deriving (Eq, Ord, Show)
|
|
Packit |
9a2dfb |
|
|
Packit |
9a2dfb |
instance Hashable a => Hashable (LogScaled a) where
|
|
Packit |
9a2dfb |
hashWithSalt salt (LogScaled a) = hashWithSalt salt a
|
|
Packit |
9a2dfb |
|
|
Packit |
9a2dfb |
instance Arbitrary a => Arbitrary (LogScaled a) where
|
|
Packit |
9a2dfb |
arbitrary = fmap LogScaled $ scale (\x -> intLog2 $ x + 1) arbitrary
|
|
Packit |
9a2dfb |
shrink = fmap LogScaled . shrink . getLogScaled
|
|
Packit |
9a2dfb |
|
|
Packit |
9a2dfb |
instance ToJSON a => ToJSON (LogScaled a) where
|
|
Packit |
9a2dfb |
toJSON (LogScaled d) = toJSON d
|
|
Packit |
9a2dfb |
toEncoding (LogScaled d) = toEncoding d
|
|
Packit |
9a2dfb |
|
|
Packit |
9a2dfb |
instance FromJSON a => FromJSON (LogScaled a) where
|
|
Packit |
9a2dfb |
parseJSON = fmap LogScaled . parseJSON
|
|
Packit |
9a2dfb |
|
|
Packit |
9a2dfb |
instance (ToJSONKey a) => ToJSONKey (LogScaled a) where
|
|
Packit |
9a2dfb |
toJSONKey = contramapToJSONKeyFunction getLogScaled toJSONKey
|
|
Packit |
9a2dfb |
toJSONKeyList = contramapToJSONKeyFunction (fmap getLogScaled) toJSONKeyList
|
|
Packit |
9a2dfb |
|
|
Packit |
9a2dfb |
instance (FromJSONKey a) => FromJSONKey (LogScaled a) where
|
|
Packit |
9a2dfb |
fromJSONKey = fmap LogScaled fromJSONKey
|
|
Packit |
9a2dfb |
fromJSONKeyList = coerceFromJSONKeyFunction (fromJSONKeyList :: FromJSONKeyFunction [a])
|