A seguinte declaração apresenta um erro:
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'
.
Agora, eu me pergunto por que essa limitação foi introduzida?
Se a limitação não existisse, alguém poderia escrever
Translate (1, 1) Rect 2 2
e
Translate (1, 2, 3) Cuboid 1 1 1
, o que parece natural.
Não vejo (imediatamente) como isso pode resultar em um problema de análise ao tentar proibir o uso do mesmo nome; o tipo pode ser inferido pelo argumento ( Rect 2 2
é um Obj2d
, Cuboid 1 1 1
é um Obj3d
).
Tenho certeza de que há uma boa razão pela qual os designers de linguagem optaram por não permitir o uso do mesmo nome para construtores de dados de tipos diferentes, mas eu gostaria de aprender: por que, quando não é obviamente necessário?
(E a desambiguação de tipo é o negócio de pão com manteiga de Haskell!)
Respostas:
Isso ocorre porque os construtores de dados são apenas funções e a sobrecarga de funções não é permitida no Haskell. Pode ficar mais claro se você usar a sintaxe do GADT para definir seus tipos:
Eu acredito que eles (os desenvolvedores do GHC) estão trabalhando em possíveis soluções para esse problema, envolvendo a introdução de um novo
type class
para todos os tipos que compartilham o mesmo construtor de dados ou algo semelhante. Portanto, fique atento, uma solução para o seu problema pode estar em breve! (Eu espero)fonte
type class
construções que você está estipulando. - O motivo é: não tenho um problema, posso fazerTranslate2
eTranslate3d
, mas prefiro não poluir o espaço para nome.