2011-07-14 68 views

Respuesta

37

Usando fromIntegral:

Prelude> let x = 5::Int 
Prelude> sqrt (fromIntegral x) 
2.23606797749979 

ambos Int y Integer son instancias de Integral:

  • fromIntegral :: (Integral a, Num b) => a -> b toma su Int (que es una instancia de Integral) y "hace" un Num.

  • sqrt :: (Floating a) => a -> a espera un Floating, y Floating Heredar del Fractional, que hereda de Num, por lo que puede pasar con seguridad a sqrt el resultado de fromIntegral

Creo que las clases diagram en Haskell Wikibook es bastante útil en este caso.

+1

¿Podría 'sqrt (fromIntegral x)' también escribirse como 'sqrt $ fromIntegral x'? – rzetterberg

+0

Sí, de hecho podría, ya que la aplicación explícita ($) no se vincula tan estrechamente como la aplicación implícita. – Edward

+0

¡sí! y también '(sqrt. fromIntegral) x' – MarcoS

10

Recuerde, la aplicación se une más estrechamente que cualquier otro operador. Eso incluye la composición. Lo que queremos es

sqrt $ fromIntegral x 

Entonces

fromIntegral x 

serán evaluados en primer lugar, porque la aplicación implícita (espacio) se une más estrechamente que la aplicación explícita ($).

Alternativamente, si desea ver cómo funcionaría composición:

(sqrt . fromIntegral) x 

paréntesis asegurarse de que el operador de composición se evalúa primero, y luego la función resultante es el lado izquierdo de la aplicación.

33

Quizás también quieras que el resultado sea Int?

isqrt :: Int -> Int 
isqrt = floor . sqrt . fromIntegral 

Es posible que desee reemplazar floor con ceiling o round. (Por cierto, esta función tiene un tipo más general que la que di).

+1

ghc advierte sobre esto, ya que no sabe qué tipo exacto usar entre 'fromIntegral' y' floor' (podría ser 'Double',' Float', etc.). Para arreglar: 'isqrt x = piso.sqrt $ (fromIntegral x :: Float) ', que es menos elegante :( –

+0

Me gusta, de todos modos. No advierte sobre GHC 8. –

Cuestiones relacionadas