10Pines / pdepreludat

BSD 3-Clause "New" or "Revised" License
24 stars 2 forks source link

Comportamiento confuso del enumFromTo #15

Closed fdodino closed 3 years ago

fdodino commented 4 years ago

Esto es lo que me tira repl.it:

image

El pdepreludat convierte todo número a float, el tema es que Haskell se comporta raro con los decimales. Habría que ver si se puede forzar a que usen enteros si corresponden para que arme bien el rango. Hoy el resultado confundió a varios alumnos:

image

ludat commented 4 years ago

Se me ocurren un par de maneras para resolver eso:

  1. Hay una libreria scientific que lo que hace es ser inteligente en la manera en la que se muestra, dependiendo si tiene componente decimal.

  2. Podriamos agregarle una parte mas al data de Number que sea si tiene componente decimal (digamos hasDecimalPlaces), entonces:

IMO la manera 2 es mas consistente pero es bastante mas terrible de implementar

JuanFdS commented 4 years ago

Update sobre el por qué de esto:

https://www.haskell.org/onlinereport/basic.html

For Float and Double, the semantics of the enumFrom family is given by the rules for Int above, except that the list terminates when the elements become greater than e3+i/2 for positive increment i, or when they become less than e3+i/2 for negative i.

O sea, al hacer [10, 8 .. 1], itera hasta encontrar alguno con margen de error de (10-8)/2, o sea, con margen de error de 1. Por eso el 0 queda adentro. Y creo que ese margen de error es para compensar errores de redondeo.

Igual, por mí +1 a en el pdepreludat hacer la nuestra y cambiar como funciona la instancia de Enum para Fractional para que funcione como enteros.

Creo que una solución posible es: agarrar los parámetros de enumFromThenTo, si todos son enteros, entonces hacer enumFromThenTo pero con los numeros convertidos a enteros, y luego mappear la lista resultante para que se vuelvan a convertir en Numbers, si alguno era decimal, hacer el enumFromThenTo con los decimales y luego convertir a Numbers