fromintegral - mod haskell
DivisiĆ³n en Haskell (2)
Estoy haciendo una función en Haskell que reduce solo los aspectos de una lista y estoy experimentando un problema. Cuando ejecuto el compilador, se queja de que no puede realizar la división de un int y que necesito una declaración de tipo int fraccional. He intentado cambiar la declaración de tipo para flotar, pero eso acaba de generar otro error. He incluido el código de la función a continuación y esperaba cualquier tipo de ayuda.
halfEvens :: [Int] -> [Int]
halfEvens [] = []
halfEvens (x:xs) | odd x = halfEvens xs
| otherwise = x/2:halfEvens xs
Gracias por leer.
Debería agregar que usar el map
simplificaría el código.
HalfIfEven n
| even n = n `div` 2
| otherwise = n
halfEvens = map halfIfEven
Use div
, que realiza la división entera:
halfEvens :: [Int] -> [Int]
halfEvens [] = []
halfEvens (x:xs) | odd x = halfEvens xs
| otherwise = x `div` 2 : halfEvens xs
La función (/)
requiere argumentos cuyo tipo está en la clase Fractional, y realiza la división estándar. La función div
requiere argumentos cuyo tipo esté en la clase Integral y realiza una división de enteros.
Más precisamente, div
y mod
redondean hacia el infinito negativo. Sus primos, quot
y rem
, se comportan como división entera en C y redondean hacia cero. div
y mod
suelen ser correctos cuando se realiza una aritmética modular (por ejemplo, al calcular el día de la semana dada una fecha), mientras que quot
y rem
son ligeramente más rápidos (creo).
Jugando un poco en GHCi:
> :t div
div :: Integral a => a -> a -> a
> :t (/)
(/) :: Fractional a => a -> a -> a
> 3 / 5
0.6
> 3 `div` 5
0
> (-3) `div` 5
-1
> (-3) `quot` 5
0
> [x `mod` 3 | x <- [-10..10]]
[2,0,1,2,0,1,2,0,1,2,0,1,2,0,1,2,0,1,2,0,1]
> [x `rem` 3 | x <- [-10..10]]
[-1,0,-2,-1,0,-2,-1,0,-2,-1,0,1,2,0,1,2,0,1,2,0,1]