-- | It is occasionally useful to define generic functions that can -- not only compute their result as an integer, but also as a symbolic -- expression in the form of an AST. -- -- There are some Haskell hacks for this - it is for example not hard -- to define an instance of 'Num' that constructs an AST. However, -- this falls down for some other interesting classes, like -- 'Integral', which requires both the problematic method -- 'fromInteger', and also that the type is an instance of 'Enum'. -- -- We can always just define hobbled instances that call 'error' for -- those methods that are impractical, but this is ugly. -- -- Hence, this module defines similes to standard Haskell numeric -- typeclasses that have been modified to make generic functions -- slightly easier to write. module Futhark.Util.IntegralExp ( IntegralExp (..) , Wrapped (..) ) where import Data.Int import Prelude -- | A twist on the 'Integral' type class that is more friendly to -- symbolic representations. class Num e => IntegralExp e where quot :: e -> e -> e rem :: e -> e -> e div :: e -> e -> e mod :: e -> e -> e sgn :: e -> Maybe Int -- | Like 'Futhark.Util.IntegralExp.div', but rounds towards -- positive infinity. divUp :: e -> e -> e divUp e x e y = (e x e -> e -> e forall a. Num a => a -> a -> a + e y e -> e -> e forall a. Num a => a -> a -> a - e 1) e -> e -> e forall e. IntegralExp e => e -> e -> e `Futhark.Util.IntegralExp.div` e y fromInt8 :: Int8 -> e fromInt16 :: Int16 -> e fromInt32 :: Int32 -> e fromInt64 :: Int64 -> e -- | This wrapper allows you to use a type that is an instance of the -- true class whenever the simile class is required. newtype Wrapped a = Wrapped { Wrapped a -> a wrappedValue :: a } deriving (Wrapped a -> Wrapped a -> Bool (Wrapped a -> Wrapped a -> Bool) -> (Wrapped a -> Wrapped a -> Bool) -> Eq (Wrapped a) forall a. Eq a => Wrapped a -> Wrapped a -> Bool forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a /= :: Wrapped a -> Wrapped a -> Bool $c/= :: forall a. Eq a => Wrapped a -> Wrapped a -> Bool == :: Wrapped a -> Wrapped a -> Bool $c== :: forall a. Eq a => Wrapped a -> Wrapped a -> Bool Eq, Eq (Wrapped a) Eq (Wrapped a) -> (Wrapped a -> Wrapped a -> Ordering) -> (Wrapped a -> Wrapped a -> Bool) -> (Wrapped a -> Wrapped a -> Bool) -> (Wrapped a -> Wrapped a -> Bool) -> (Wrapped a -> Wrapped a -> Bool) -> (Wrapped a -> Wrapped a -> Wrapped a) -> (Wrapped a -> Wrapped a -> Wrapped a) -> Ord (Wrapped a) Wrapped a -> Wrapped a -> Bool Wrapped a -> Wrapped a -> Ordering Wrapped a -> Wrapped a -> Wrapped a forall a. Eq a -> (a -> a -> Ordering) -> (a -> a -> Bool) -> (a -> a -> Bool) -> (a -> a -> Bool) -> (a -> a -> Bool) -> (a -> a -> a) -> (a -> a -> a) -> Ord a forall a. Ord a => Eq (Wrapped a) forall a. Ord a => Wrapped a -> Wrapped a -> Bool forall a. Ord a => Wrapped a -> Wrapped a -> Ordering forall a. Ord a => Wrapped a -> Wrapped a -> Wrapped a min :: Wrapped a -> Wrapped a -> Wrapped a $cmin :: forall a. Ord a => Wrapped a -> Wrapped a -> Wrapped a max :: Wrapped a -> Wrapped a -> Wrapped a $cmax :: forall a. Ord a => Wrapped a -> Wrapped a -> Wrapped a >= :: Wrapped a -> Wrapped a -> Bool $c>= :: forall a. Ord a => Wrapped a -> Wrapped a -> Bool > :: Wrapped a -> Wrapped a -> Bool $c> :: forall a. Ord a => Wrapped a -> Wrapped a -> Bool <= :: Wrapped a -> Wrapped a -> Bool $c<= :: forall a. Ord a => Wrapped a -> Wrapped a -> Bool < :: Wrapped a -> Wrapped a -> Bool $c< :: forall a. Ord a => Wrapped a -> Wrapped a -> Bool compare :: Wrapped a -> Wrapped a -> Ordering $ccompare :: forall a. Ord a => Wrapped a -> Wrapped a -> Ordering $cp1Ord :: forall a. Ord a => Eq (Wrapped a) Ord, Int -> Wrapped a -> ShowS [Wrapped a] -> ShowS Wrapped a -> String (Int -> Wrapped a -> ShowS) -> (Wrapped a -> String) -> ([Wrapped a] -> ShowS) -> Show (Wrapped a) forall a. Show a => Int -> Wrapped a -> ShowS forall a. Show a => [Wrapped a] -> ShowS forall a. Show a => Wrapped a -> String forall a. (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a showList :: [Wrapped a] -> ShowS $cshowList :: forall a. Show a => [Wrapped a] -> ShowS show :: Wrapped a -> String $cshow :: forall a. Show a => Wrapped a -> String showsPrec :: Int -> Wrapped a -> ShowS $cshowsPrec :: forall a. Show a => Int -> Wrapped a -> ShowS Show) liftOp :: (a -> a) -> Wrapped a -> Wrapped a liftOp :: (a -> a) -> Wrapped a -> Wrapped a liftOp a -> a op (Wrapped a x) = a -> Wrapped a forall a. a -> Wrapped a Wrapped (a -> Wrapped a) -> a -> Wrapped a forall a b. (a -> b) -> a -> b $ a -> a op a x liftOp2 :: (a -> a -> a) -> Wrapped a -> Wrapped a -> Wrapped a liftOp2 :: (a -> a -> a) -> Wrapped a -> Wrapped a -> Wrapped a liftOp2 a -> a -> a op (Wrapped a x) (Wrapped a y) = a -> Wrapped a forall a. a -> Wrapped a Wrapped (a -> Wrapped a) -> a -> Wrapped a forall a b. (a -> b) -> a -> b $ a x a -> a -> a `op` a y instance Num a => Num (Wrapped a) where + :: Wrapped a -> Wrapped a -> Wrapped a (+) = (a -> a -> a) -> Wrapped a -> Wrapped a -> Wrapped a forall a. (a -> a -> a) -> Wrapped a -> Wrapped a -> Wrapped a liftOp2 a -> a -> a forall a. Num a => a -> a -> a (Prelude.+) (-) = (a -> a -> a) -> Wrapped a -> Wrapped a -> Wrapped a forall a. (a -> a -> a) -> Wrapped a -> Wrapped a -> Wrapped a liftOp2 a -> a -> a forall a. Num a => a -> a -> a (Prelude.-) * :: Wrapped a -> Wrapped a -> Wrapped a (*) = (a -> a -> a) -> Wrapped a -> Wrapped a -> Wrapped a forall a. (a -> a -> a) -> Wrapped a -> Wrapped a -> Wrapped a liftOp2 a -> a -> a forall a. Num a => a -> a -> a (Prelude.*) abs :: Wrapped a -> Wrapped a abs = (a -> a) -> Wrapped a -> Wrapped a forall a. (a -> a) -> Wrapped a -> Wrapped a liftOp a -> a forall a. Num a => a -> a Prelude.abs signum :: Wrapped a -> Wrapped a signum = (a -> a) -> Wrapped a -> Wrapped a forall a. (a -> a) -> Wrapped a -> Wrapped a liftOp a -> a forall a. Num a => a -> a Prelude.signum fromInteger :: Integer -> Wrapped a fromInteger = a -> Wrapped a forall a. a -> Wrapped a Wrapped (a -> Wrapped a) -> (Integer -> a) -> Integer -> Wrapped a forall b c a. (b -> c) -> (a -> b) -> a -> c . Integer -> a forall a. Num a => Integer -> a Prelude.fromInteger negate :: Wrapped a -> Wrapped a negate = (a -> a) -> Wrapped a -> Wrapped a forall a. (a -> a) -> Wrapped a -> Wrapped a liftOp a -> a forall a. Num a => a -> a Prelude.negate instance Integral a => IntegralExp (Wrapped a) where quot :: Wrapped a -> Wrapped a -> Wrapped a quot = (a -> a -> a) -> Wrapped a -> Wrapped a -> Wrapped a forall a. (a -> a -> a) -> Wrapped a -> Wrapped a -> Wrapped a liftOp2 a -> a -> a forall a. Integral a => a -> a -> a Prelude.quot rem :: Wrapped a -> Wrapped a -> Wrapped a rem = (a -> a -> a) -> Wrapped a -> Wrapped a -> Wrapped a forall a. (a -> a -> a) -> Wrapped a -> Wrapped a -> Wrapped a liftOp2 a -> a -> a forall a. Integral a => a -> a -> a Prelude.rem div :: Wrapped a -> Wrapped a -> Wrapped a div = (a -> a -> a) -> Wrapped a -> Wrapped a -> Wrapped a forall a. (a -> a -> a) -> Wrapped a -> Wrapped a -> Wrapped a liftOp2 a -> a -> a forall a. Integral a => a -> a -> a Prelude.div mod :: Wrapped a -> Wrapped a -> Wrapped a mod = (a -> a -> a) -> Wrapped a -> Wrapped a -> Wrapped a forall a. (a -> a -> a) -> Wrapped a -> Wrapped a -> Wrapped a liftOp2 a -> a -> a forall a. Integral a => a -> a -> a Prelude.mod sgn :: Wrapped a -> Maybe Int sgn = Int -> Maybe Int forall a. a -> Maybe a Just (Int -> Maybe Int) -> (Wrapped a -> Int) -> Wrapped a -> Maybe Int forall b c a. (b -> c) -> (a -> b) -> a -> c . Integer -> Int forall a b. (Integral a, Num b) => a -> b fromIntegral (Integer -> Int) -> (Wrapped a -> Integer) -> Wrapped a -> Int forall b c a. (b -> c) -> (a -> b) -> a -> c . Integer -> Integer forall a. Num a => a -> a signum (Integer -> Integer) -> (Wrapped a -> Integer) -> Wrapped a -> Integer forall b c a. (b -> c) -> (a -> b) -> a -> c . a -> Integer forall a. Integral a => a -> Integer toInteger (a -> Integer) -> (Wrapped a -> a) -> Wrapped a -> Integer forall b c a. (b -> c) -> (a -> b) -> a -> c . Wrapped a -> a forall a. Wrapped a -> a wrappedValue fromInt8 :: Int8 -> Wrapped a fromInt8 = Integer -> Wrapped a forall a. Num a => Integer -> a fromInteger (Integer -> Wrapped a) -> (Int8 -> Integer) -> Int8 -> Wrapped a forall b c a. (b -> c) -> (a -> b) -> a -> c . Int8 -> Integer forall a. Integral a => a -> Integer toInteger fromInt16 :: Int16 -> Wrapped a fromInt16 = Integer -> Wrapped a forall a. Num a => Integer -> a fromInteger (Integer -> Wrapped a) -> (Int16 -> Integer) -> Int16 -> Wrapped a forall b c a. (b -> c) -> (a -> b) -> a -> c . Int16 -> Integer forall a. Integral a => a -> Integer toInteger fromInt32 :: Int32 -> Wrapped a fromInt32 = Integer -> Wrapped a forall a. Num a => Integer -> a fromInteger (Integer -> Wrapped a) -> (Int32 -> Integer) -> Int32 -> Wrapped a forall b c a. (b -> c) -> (a -> b) -> a -> c . Int32 -> Integer forall a. Integral a => a -> Integer toInteger fromInt64 :: Int64 -> Wrapped a fromInt64 = Integer -> Wrapped a forall a. Num a => Integer -> a fromInteger (Integer -> Wrapped a) -> (Int64 -> Integer) -> Int64 -> Wrapped a forall b c a. (b -> c) -> (a -> b) -> a -> c . Int64 -> Integer forall a. Integral a => a -> Integer toInteger