-- | Type-level functions on result types. -- -- Linear functions are classified as either int-valued or real-valued, -- so we define @KZ@ and @KR@ as data kinds to denote this in the type. -- module Numeric.Limp.Program.ResultKind where import Numeric.Limp.Rep -- | Classify the result type of a linear function to either integral or real: data K -- | Integral @Z@ = KZ -- | Real or mixed @R@ | KR -- | Representation of either integral of real linear functions: -- a list of variables with coefficients, plus a constant summand. data Linear z r c k where LZ :: [(z, Z c)] -> (Z c) -> Linear z r c 'KZ LR :: [(Either z r, R c)] -> (R c) -> Linear z r c 'KR deriving instance (Show z, Show r, Show (Z c), Show (R c)) => (Show (Linear z r c k)) -- | Find the result type of merging, or adding, two linear functions: -- adding two integers produces an integer, while adding a real on either side produces a real. type family KMerge (a :: K) (b :: K) :: K where KMerge 'KZ 'KZ = 'KZ KMerge 'KR b = 'KR KMerge a 'KR = 'KR -- | Convert a @K@ to its actual representation (@Z@ or @R@). type family KRep (a :: K) :: * -> * where KRep 'KZ = Z KRep 'KR = R