Perché i costruttori di dati con lo stesso nome non sono consentiti nei costruttori di tipi diversi?


11

La seguente dichiarazione fornisce un errore:

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

vale a dire Multiple declarations of 'Translate'.

Ora, mi chiedo perché questa limitazione sia stata introdotta?

Se la limitazione non fosse presente, si potrebbe scrivere

Translate (1, 1) Rect 2 2 e Translate (1, 2, 3) Cuboid 1 1 1, che suona naturale.

Non vedo (immediatamente) come ciò possa comportare un problema di analisi delle offerte per non consentire l'utilizzo dello stesso nome, il tipo potrebbe essere dedotto dall'argomento ( Rect 2 2è un Obj2d, Cuboid 1 1 1è un Obj3d).

Sono sicuro che c'è una buona ragione per cui i progettisti del linguaggio hanno scelto di non consentire l'uso dello stesso nome per costruttori di dati di tipi diversi, ma mi piacerebbe imparare: perché, quando ovviamente non è necessario?

(E il tipo di chiarimento è il business del pane e burro di Haskell!)


3
Per quanto riguarda il tipo inferito dall'argomento: sei consapevole che a volte il tipo dell'argomento viene dedotto dal tipo della funzione ?

@delnan Non ne ero a conoscenza ... sembra una risposta per me. Ho sempre pensato che l'inferenza fosse dal basso verso l'alto, anche se ho potuto vedere la risoluzione dell'ambiguità usando le informazioni sul tipo dall'altro lato del grafico dei tipi mentre descrivi come un fattore decisivo ... la mia immagine mentale per questo è i tipi di ritorno nella parte inferiore del grafico e chiamate di funzione in alto, la risoluzione è un aggregato formato piegando verso l'alto dal basso, ma non è esattamente l' intera immagine, è quello che stai dicendo? Non sorprende che in un linguaggio tipicamente dipendente con perfetta inferenza ciò sia probabilmente più accurato ..
Jimmy Hoffa,

Risposte:


13

Questo perché i costruttori di dati sono solo funzioni e il sovraccarico delle funzioni non è consentito in Haskell. Potrebbe essere più chiaro se usi la sintassi GADT per definire i tuoi tipi:

{-# LANGUAGE GADTs #-}
data Obj2d where
    Rect :: Float -> Float -> Obj2d   -- a function from floats to obj2d's
    Translate :: Vec2d -> Obj2d       -- a function from vec2d's to Obj2d's

Credo che (gli sviluppatori GHC) stiano lavorando su possibili soluzioni a questo problema, introducendo un nuovo type classper tutti i tipi che condividono lo stesso costruttore di dati o qualcosa di simile. Quindi rimanete sintonizzati, una soluzione al vostro problema potrebbe arrivare presto! (Io spero)


Non vedo l'ora di vedere questi type classcostrutti che stai stipulando. - Il motivo è: non ho problemi, posso farlo Translate2e Translate3d, ma preferirei non inquinare lo spazio dei nomi.
A Sz,

Non sono uno sviluppatore di GHC, quindi è solo sentito dire. Spero che accada anche.
bstamour,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.