{-# LANGUAGE DeriveAnyClass #-} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE LambdaCase #-} {-# OPTIONS_GHC -Wno-orphans #-} module Data.Function.FastMemo.Integer () where import Data.Function.FastMemo.Class (Memoizable (..)) import Data.Function.FastMemo.Natural () import GHC.Generics (Generic) import Numeric.Natural (Natural) instance Memoizable Integer where memoize :: (Integer -> b) -> Integer -> b memoize Integer -> b f = ((Sign, Natural) -> b) -> (Sign, Natural) -> b forall a b. Memoizable a => (a -> b) -> a -> b memoize (Integer -> b f (Integer -> b) -> ((Sign, Natural) -> Integer) -> (Sign, Natural) -> b forall b c a. (b -> c) -> (a -> b) -> a -> c . (Sign, Natural) -> Integer signedNatToInteger) ((Sign, Natural) -> b) -> (Integer -> (Sign, Natural)) -> Integer -> b forall b c a. (b -> c) -> (a -> b) -> a -> c . Integer -> (Sign, Natural) integerToSignedNat data Sign = NegativePlus1 | NonNegative deriving ((forall x. Sign -> Rep Sign x) -> (forall x. Rep Sign x -> Sign) -> Generic Sign forall x. Rep Sign x -> Sign forall x. Sign -> Rep Sign x forall a. (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a $cto :: forall x. Rep Sign x -> Sign $cfrom :: forall x. Sign -> Rep Sign x Generic, (forall b. (Sign -> b) -> Sign -> b) -> Memoizable Sign forall b. (Sign -> b) -> Sign -> b forall a. (forall b. (a -> b) -> a -> b) -> Memoizable a memoize :: (Sign -> b) -> Sign -> b $cmemoize :: forall b. (Sign -> b) -> Sign -> b Memoizable) integerToSignedNat :: Integer -> (Sign, Natural) integerToSignedNat :: Integer -> (Sign, Natural) integerToSignedNat Integer i | Integer i Integer -> Integer -> Bool forall a. Ord a => a -> a -> Bool < Integer 0 = (Sign NegativePlus1, Integer -> Natural forall a. Num a => Integer -> a fromInteger (- (Integer i Integer -> Integer -> Integer forall a. Num a => a -> a -> a + Integer 1))) | Bool otherwise = (Sign NonNegative, Integer -> Natural forall a. Num a => Integer -> a fromInteger Integer i) signedNatToInteger :: (Sign, Natural) -> Integer signedNatToInteger :: (Sign, Natural) -> Integer signedNatToInteger = \case (Sign NegativePlus1, Natural n) -> - (Natural -> Integer forall a. Integral a => a -> Integer toInteger Natural n Integer -> Integer -> Integer forall a. Num a => a -> a -> a + Integer 1) (Sign NonNegative, Natural n) -> Natural -> Integer forall a. Integral a => a -> Integer toInteger Natural n