-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/

-- | Integer roots and perfect powers
--   
--   Calculating integer roots and testing perfect powers of arbitrary
--   precision. Originally part of arithmoi package.
@package integer-roots
@version 1.0.4.0

-- | Calculating integer roots and testing perfect powers.
module Math.NumberTheory.Roots

-- | For a non-negative input <math> calculate its integer square
--   root <math>. Throw an error on negative input.
--   
--   
--   >>> integerSquareRoot 99
--   9
--   
--   >>> integerSquareRoot 100
--   10
--   
--   >>> integerSquareRoot 101
--   10
--   
integerSquareRoot :: Integral a => a -> a

-- | Test whether the argument is a perfect square.
--   
--   
--   >>> map isSquare [-100, 99, 100, 101]
--   [False,False,True,False]
--   
isSquare :: Integral a => a -> Bool

-- | Calculate the exact integer square root if it exists, otherwise return
--   Nothing.
--   
--   
--   >>> map exactSquareRoot [-100, 99, 100, 101]
--   [Nothing,Nothing,Just 10,Nothing]
--   
exactSquareRoot :: Integral a => a -> Maybe a

-- | For a given <math> calculate its integer cube root <math>.
--   Note that this is not symmetric about 0.
--   
--   
--   >>> map integerCubeRoot [7, 8, 9]
--   [1,2,2]
--   
--   >>> map integerCubeRoot [-7, -8, -9]
--   [-2,-2,-3]
--   
integerCubeRoot :: Integral a => a -> a

-- | Test whether the argument is a perfect cube.
--   
--   
--   >>> map isCube [-9, -8, -7, 7, 8, 9]
--   [False,True,False,False,True,False]
--   
isCube :: Integral a => a -> Bool

-- | Calculate the exact integer cube root if it exists, otherwise return
--   Nothing.
--   
--   
--   >>> map exactCubeRoot [-9, -8, -7, 7, 8, 9]
--   [Nothing,Just (-2),Nothing,Nothing,Just 2,Nothing]
--   
exactCubeRoot :: Integral a => a -> Maybe a

-- | For a positive power <math> and a given <math> return the
--   integer <math>-th root <math>. Throw an error if
--   <math> or if <math> and <math> is even.
--   
--   
--   >>> integerRoot 6 65
--   2
--   
--   >>> integerRoot 5 243
--   3
--   
--   >>> integerRoot 4 624
--   4
--   
--   >>> integerRoot 3 (-124)
--   -5
--   
--   >>> integerRoot 1 5
--   5
--   
integerRoot :: (Integral a, Integral b) => b -> a -> a

-- | For a positive exponent <math> test whether the second argument
--   is a perfect <math>-th power.
--   
--   
--   >>> map (uncurry isKthPower) [(6, 65), (5, 243), (4, 624), (3, -124), (1, 5)]
--   [False,True,False,False,True]
--   
isKthPower :: (Integral a, Integral b) => b -> a -> Bool

-- | For a positive exponent <math> calculate the exact integer
--   <math>-th root of the second argument if it exists, otherwise
--   return Nothing.
--   
--   
--   >>> map (uncurry exactRoot) [(6, 65), (5, 243), (4, 624), (3, -124), (1, 5)]
--   [Nothing,Just 3,Nothing,Nothing,Just 5]
--   
exactRoot :: (Integral a, Integral b) => b -> a -> Maybe a

-- | Test whether the argument is a non-trivial perfect power (e. g.,
--   square, cube, etc.).
--   
--   
--   >>> map isPerfectPower [0..10]
--   [True,True,False,False,True,False,False,False,True,True,False]
--   
--   >>> map isPerfectPower [-10..0]
--   [False,False,True,False,False,False,False,False,False,True,True]
--   
isPerfectPower :: Integral a => a -> Bool

-- | For <math> find the largest exponent <math> for which an
--   exact integer <math>-th root <math> exists. Return
--   <math>.
--   
--   For <math> arbitrarily large exponents exist; by arbitrary
--   convention highestPower returns <math>.
--   
--   
--   >>> map highestPower [0..10]
--   [(0,3),(1,3),(2,1),(3,1),(2,2),(5,1),(6,1),(7,1),(2,3),(3,2),(10,1)]
--   
--   >>> map highestPower [-10..0]
--   [(-10,1),(-9,1),(-2,3),(-7,1),(-6,1),(-5,1),(-4,1),(-3,1),(-2,1),(-1,3),(0,3)]
--   
highestPower :: Integral a => a -> (a, Word)
