Quali sono gli usi dei tipi di dati algebrici?

15

Sto leggendo su Tipi di dati algebrici (grazie a Richard Minerich ho trovato questo spiegazione eccellente del concetto). Mentre penso di capire la nozione di tipi di somma e tipi di prodotto ecc., Quello che non sto capendo è come i tipi di dati algebrici siano utili oltre a specificare la corrispondenza dei modelli. Quali altre cose si possono fare con ADT oltre al pattern matching?

EDIT: Non sto chiedendo cosa può fare uno sviluppatore con ADT che non può essere fatto con gli oggetti. Sto chiedendo se ci sono altre operazioni consentite da ADT; per esempio, si può fare un ragionamento in più sui tipi coinvolti se vengono impiegati ADT? Le ADT facilitano una sorta di analisi del tipo che non sarebbe possibile senza di loro?

    
posta Onorio Catenacci 05.05.2011 - 16:10
fonte

2 risposte

10

I tipi di dati algebrici sono distinti in quanto possono essere costruiti da diversi tipi di "cose". Ad esempio, un albero non può contenere nulla (vuoto), una foglia o un nodo.

data Tree = Empty
          | Leaf Int
          | Node Tree Tree

Poiché un nodo è composto da due alberi, i tipi di dati algebrici possono essere ricorsivi.

La corrispondenza dei modelli consente ai tipi di dati algebrici di essere decostruiti in modo da mantenere la sicurezza del tipo. Considera la seguente implementazione della profondità e il suo equivalente pseudocodice:

depth :: Tree -> Int
depth Empty = 0
depth (Leaf n) = 1
depth (Node l r) = 1 + max (depth l) (depth r)

rispetto a:

switch on (data.constructor)
  case Empty:
    return 0
  case Leaf:
    return 1
  case Node:
    let l = data.field1
    let r = data.field2
    return 1 + max (depth l) (depth r)

Questo ha lo svantaggio che il programmatore deve ricordare il caso Empty prima di Leaf in modo che il campo 1 non sia accessibile su un albero vuoto. Allo stesso modo, la custodia Leaf deve essere dichiarata prima del caso Nodo in modo che il campo 2 non sia accessibile su Leaf. Quindi la sicurezza del tipo non è quindi mantenuta dal linguaggio, ma piuttosto impone un carico cognitivo aggiuntivo sul programmatore. A proposito, sto prendendo questi esempi direttamente dalle pagine di Wikipedia.

Ovviamente, una langauge che digita le anatre potrebbe fare qualcosa del genere:

class Empty
  def depth
    0
  end
end

class Leaf
  def depth
    1
  end
end

class Node
  attr_accessor :field1, :field2

  def depth
    1 + [field1.depth, field2.depth].max
  end
end

Quindi i tipi di dati algebrici potrebbero non essere strettamente migliori del loro equivalente OOP, ma forniscono un diverso insieme di tensioni su cui lavorare durante la costruzione del software.

    
risposta data 05.05.2011 - 17:49
fonte
9

Non sono così sicuro che la spiegazione sia quella eccellente.

I tipi di dati algebrici vengono utilizzati per creare strutture di dati, come elenchi e alberi.

Ad esempio, gli alberi di analisi sono facilmente rappresentati con strutture di dati algebrici.

data BinOperator = Add
                 | Subtr
                 | Div
                 | Mult
                 | Mod
                 | Eq
                 | NotEq
                 | GreaterThan
                 | LogicAnd
                 | LogicOr
                 | BitAnd
                 | BitOr
                 | ...

data UnOperator = Negate
                | Not
                | Increment
                | Decrement
                | Complement
                | Ref
                | DeRef


data Expression = Empty
                | IntConst Int
                | FloatConst Float
                | StringConst String
                | Ident String
                | BinOp BinOperator Expression Expression
                | UnOp UnOperator Expression Bool //prefix or not
                | If Expression Expression Expression
                | While Expression Expression Bool //while vs. do while
                | Block List<Expression>
                | Call Expression List<Expression>
                | ...

In realtà non servirebbe molto di più per rappresentare il linguaggio C.

Ma in realtà, puoi fare TUTTO con tipi di dati algebrici. Lisp dimostra che puoi fare tutto con coppie e ADT semplicemente fornire un modo più granulare e sicuro per questo approccio.

Naturalmente, se chiedi "Cosa puoi fare con gli ADT, che non puoi fare con gli oggetti?", la risposta è "nulla". Solo a volte (soprattutto) troverete che le soluzioni sugli ADT sono significativamente meno prolisse, mentre quelle basate sugli oggetti sono probabilmente più flessibili. Quindi, per inserirlo in un albero di analisi rappresentato con ADT:

If(Call(Ident('likes_ADTs'),[Ident('you')]),
   Call(Ident('use_ADTs'),[Ident('you')]),
   Call(Ident('use_no_ADTs'),[Ident('you')]))
    
risposta data 05.05.2011 - 16:46
fonte

Leggi altre domande sui tag