fromintegral frominteger float convertir haskell integer double

float - frominteger haskell



Uso excesivo de fromIntegral en Haskell (4)

A veces encuentro útil una función de ayuda:

roundDouble x acc = (round $ x * 10 ^ acc) /. (10 ^ acc) where x /. y = fromIntegral x / fromIntegral y

Esa función auxiliar también se puede escribir:

(/.) = (/) `on` fromIntegral

Donde on es de Data.Function .

Cada vez que escribo una función usando dobles y enteros, encuentro este problema donde constantemente tengo que usar ''fromIntegral'' en todas partes en mi función. Por ejemplo:

import Data.List roundDouble :: Double -> Int -> Double roundDouble x acc = fromIntegral (round $ x * 10 ** fromIntegral acc) / 10 ** fromIntegral acc

¿Hay una forma más fácil de escribir esto? (Sé que puede haber formas más fáciles de redondear un número y, si las hay, hágamelo saber. Sin embargo, me interesa sobre todo cómo evitar el uso de tantos "desde los Integrales").

Gracias ash


Otra idea, similar a la de luqui''s . La mayoría de mis problemas con fromIntegral están relacionados con la necesidad de dividir Int por Double o Double por Int . Entonces (/.) Permite dividir cualquiera de los dos tipos Real , no necesariamente iguales, y no necesariamente tipos Integral como en la solución de luqui:

(/.) :: (Real a, Real b, Fractional c) => a -> b -> c (/.) x y = fromRational $ (toRational x) / (toRational y)

Ejemplo:

ghci> let (a,b,c) = (2::Int, 3::Double, 5::Int) ghci> (b/.a, c/.a, a/.c) (1.5,2.5,0.4)

Funciona para dos Real , pero sospecho que la división racional y la conversión a / desde Rational no son muy efectivas.

Ahora tu ejemplo se convierte en:

roundDouble :: Double -> Int -> Double roundDouble x acc = (round $ x * 10 ^ acc) /. (10 ^ acc)


Puedes usar ^ lugar de ** . ^ toma cualquier Integral como segundo argumento, por lo que no es necesario que llames desde fromIntegral al segundo operando. Entonces tu código se convierte en:

roundDouble x acc = fromIntegral (round $ x * 10 ^ acc) / 10 ^ acc

Que solo tiene uno de fromIntegral . Y ese que no puede deshacerse ya que la round naturalmente devuelve un Integral y no puede realizar una división no entera en un Integral.


Tengo un problema similar con el código de fromIntegral , donde se utiliza fromIntegral para convertir CInt a Int. Generalmente defino fI = fromIntegral para hacerlo más fácil. Es posible que también deba darle una firma de tipo explícita o usar -XNoMonomorphismRestriction.

Si estás haciendo muchos cálculos, es posible que desees ver el Preludio numérico , que parece tener relaciones mucho más sensibles entre los diferentes tipos numéricos.