... but due to this being Haskell you cant use variables to keep the original n.
I don't know what makes you say that. Here's how you could implement it:
intSquareRoot :: Int -> Int
intSquareRoot n = aux n
where
aux x
| x*x > n = aux (x - 1)
| otherwise = x
This is good enough to play around, but it's not a very efficient implementation. A better one can be found on Haskell's wiki:
(^!) :: Num a => a -> Int -> a
(^!) x n = x^n
squareRoot :: Integer -> Integer
squareRoot 0 = 0
squareRoot 1 = 1
squareRoot n =
let twopows = iterate (^!2) 2
(lowerRoot, lowerN) =
last $ takeWhile ((n>=) . snd) $ zip (1:twopows) twopows
newtonStep x = div (x + div n x) 2
iters = iterate newtonStep (squareRoot (div n lowerN) * lowerRoot)
isRoot r = r^!2 <= n && n < (r+1)^!2
in head $ dropWhile (not . isRoot) iters
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…