È possibile unificare gli ADULT con classi di tipi?

1

Quando pensavo al design del linguaggio mi sono reso conto che gli ADT (tipi di dati di Aglebraic) e le classificazioni potrebbero essere la stessa cosa. Possono entrambi rappresentare un gruppo di tipi, ma in haskell non sono la stessa cosa. Typeclass può essere esteso in seguito, ma ADT non può.

Ma a volte anche la classe di tipizzazione non può fare tutto ciò che un ADT può fare. Ad esempio:

class Shape a where
  draw :: a -> IO ()

data Rectangle = Rectangle Float Float
instance Shape Rectangle where
  draw rectangle = ...

-- no way to put constraint for shape
data Group a = Group [a]
instance Shape Group wheres
  draw group = ...

Con ADT è semplice e funzionante, ma non è possibile aggiungere nuove forme:

data Shape
  = Rectangle Float Float
  | Group [Shape]

draw (Rectangle x y) = ...
draw (Group [ss]) = ...

Se le classi fossero più simili agli ADT, la lingua potrebbe comportarsi in modo simile quando si tratta di booleani (questa non è la sintassi di un vero programma):

-- a group of types
class Bool
-- one type with one constructor
data True
-- adding type to group
instance Bool True

data False
instance Bool False

Questo potrebbe anche essere fatto con i numeri, che sembrerebbero ancora più ridicoli, ma spero che tu possa ottenere il mio punto.

È possibile che in altre lingue queste due cose siano una? Qualunque altra lingua funziona in questo modo? Quali sono le ragioni per cui ADT e typeclass devono essere separati?

    
posta ivokosir 07.02.2015 - 16:31
fonte

1 risposta

4

Digitare classi e tipi di dati algebrici non sono affatto la stessa cosa. Non sono abbastanza opposti ma hanno scopi molto diversi

  1. Tipo classe: definisce un insieme di funzioni (di solito solo la firma, senza implementazione concreta, sebbene possa essere fornita un'implementazione predefinita). In qualsiasi punto del codice (non solo nel modulo pertinente) può essere definita un'istanza per fornire un'implementazione concreta per un tipo specifico, per aggiungerla alla classe del tipo. La creazione di questa istanza può essere una comodità temporanea e non esprimere nulla sulla natura e lo scopo della classe. L'aggiunta di un tipo a una classe di caratteri dice nulla sulla sua relazione con altri tipi. Ad hoc Il polimorfismo è l'obiettivo.
  2. ADT: un tipo di composito molto specifico creato da un insieme di costrutti più semplici che insieme definiscono i diversi stati o strutture dell'ADT. Un ADT può non avere funzioni al di là dei costruttori: potrebbe fornire un modulo List molto semplice che solo è costituito da Elenco dati a = Nil | Cons a (List a) e dire alle persone "Usa pattern matching per ottenere i dati, scrivi le tue funzioni head e tail" . Quelle funzioni fornite con un ADT saranno concreti e hard coded per trattare in modo specifico con l'insieme fisso di tipi di membri. La relazione tra i tipi di membri è ciò che l'ADT definisce (autorevolmente e infine). Il punto principale è definire espressamente i diversi stati del tipo in un modo che faciliti la scrittura di funzioni per esso, riducendo al minimo il rischio di creare accidentalmente funzioni parziali e consentire al compilatore di ottimizzare laddove la corrispondenza dei pattern è esaustiva.

They can both represent a group of types

Nell'implementazione Haskell, un ADT consiste tipicamente di un solo tipo - l'ADT stesso. L'insieme di costruttori di dati che l'ADT comprende sono valori, non tipi. Bool è un tipo ma nulla può essere di tipo True o False . Se crei un tipo Albero con costruttori Vuoto e Nodo , nulla può essere di tipo Nodo o Vuoto, solo di tipo Albero che può avere un valore Vuoto o Nodo. Questa è una caratteristica fondamentale, che consente di incapsulare i dettagli di implementazione (se lo si desidera) e di impedire l'estensione all'insieme di valori (che potrebbe rompere la struttura del tipo e le funzioni che funzionano con esso). Questo è praticamente l'opposto della Type Class, dove (ovviamente) ogni membro è un tipo e l'insieme di tipi che sono membri della classe è infinitamente estensibile.

Quasi l'unica cosa che hanno in comune è che fanno parte dello stesso sistema di tipi. Nessuna caratteristica trarrebbe beneficio dall'acquisizione delle caratteristiche dell'altro. Gli ADT sarebbero indeboliti fino al punto di inutilità (e di assurdità) diventando perdenti e ad hoc. Le classi di tipi non servirebbero se dovessero essere concreti e risolti. Questa è la mia risposta alla tua domanda finale.

Non suggerisci alcun beneficio dall'unificarli. Che cosa avevi in mente?

I tipi di dati algebrici sono molto comuni nei linguaggi funzionali. Le classi di tipi sono state inventate in Haskell e sono molto meno comuni - le comunità di sviluppo dei linguaggi funzionali più vecchi non hanno mostrato alcun entusiasmo per adottarle. Tra le poche lingue più recenti che ho, non ne conosco nessuna che abbia provato quello che suggerisci (nemmeno Scala).

    
risposta data 08.02.2015 - 03:46
fonte

Leggi altre domande sui tag