creo que el código que ya ha proporcionado es el más rápido que se va a obtener:
is_square n = sq * sq == n
where sq = floor $ sqrt $ (fromIntegral n::Double)
La complejidad de este código es: una raíz cuadrada, una multiplicación doble, un molde (dbl-> int), y una comparación Podría intentar usar otros métodos de cálculo para reemplazar el sqrt y la multiplicación con aritmética y cambios enteros, pero es probable que no vaya a ser más rápido que un sqrt y una multiplicación.
El único lugar donde podría valer la pena utilizar otro método es si la CPU en la que se está ejecutando no es compatible con la aritmética de coma flotante. En este caso, el compilador probablemente tendrá que generar sqrt y multiplicación doble en el software, y podría obtener ventajas en la optimización para su aplicación específica.
Como se señala en otra respuesta, todavía hay una limitación de enteros grandes, pero a menos que vaya a encontrar esos números, probablemente sea mejor aprovechar el soporte de hardware de punto flotante que escribir su propio algoritmo.
posible duplicar de [La forma más rápida de determinar si la raíz cuadrada de un entero es un número entero] (http: // stackoverflow.com/questions/295579/fastest-way-to-determination-if-an-integers-square-root-is-an-integer) – finnw