La siguiente declaración da un error:
type Vec2d = (Float, Float)
type Vec3d = (Float, Float, Float)
-- Rect x y defines a rectangle spanning from (0,0) to (x,y)
data Obj2d = Rect Float Float
| Translate Vec2d Obj2d
-- Cuboid x y z defines a cuboid spanning from (0,0,0) to (x,y,z)
data Obj3d = Cuboid Float Float Float
| Translate Vec3d Obj3d
a saber Multiple declarations of 'Translate'
.
Ahora, me pregunto por qué se introdujo esta limitación.
Si la limitación no estuviera allí, uno podría escribir
Translate (1, 1) Rect 2 2
y
Translate (1, 2, 3) Cuboid 1 1 1
, lo que suena natural.
No veo (de inmediato) cómo esto podría resultar en un problema de análisis al intentar no usar el mismo nombre, el argumento podría inferir el tipo ( Rect 2 2
es un Obj2d
, Cuboid 1 1 1
es un Obj3d
).
Estoy seguro de que hay una buena razón por la que los diseñadores de idiomas decidieron no usar el mismo nombre para constructores de datos de diferentes tipos, pero me gustaría aprender: ¿por qué, cuando obviamente no es necesario?
(¡Y la desambiguación de tipos es el negocio de pan y mantequilla de Haskell!)
Respuestas:
Esto se debe a que los constructores de datos son solo funciones, y la sobrecarga de funciones no está permitida en Haskell. Puede ser más claro si usa la sintaxis GADT para definir sus tipos:
Creo que ellos (los desarrolladores de GHC) están trabajando en posibles soluciones a este problema que implican la introducción de una nueva
type class
para todos los tipos que comparten el mismo constructor de datos, o algo similar. ¡Estén atentos, una solución a su problema puede llegar pronto! (Espero)fuente
type class
construcciones que está estipulando. - La razón es: no tengo un problema, puedo hacerloTranslate2
yTranslate3d
prefiero no contaminar el espacio de nombres.