Perché le unioni discriminate sono associate alla programmazione funzionale?

28

In molti anni di programmazione OO ho capito quali sono i sindacati discriminati, ma non li ho mai veramente mancati. Recentemente ho fatto alcune programmazioni funzionali in C # e ora trovo che continuo a desiderare di averle. Questo mi sconcerta perché, a prima vista, il concetto di unioni discriminate sembra del tutto indipendente dalla dicotomia funzionale / OO.

Esiste qualcosa di intrinseco nella programmazione funzionale che rende i sindacati discriminati più utili di quelli che sarebbero in OO, o è che costringendomi ad analizzare il problema in un modo "migliore", ho semplicemente migliorato i miei standard e ora richiedere un modello migliore?

    
posta Andy 07.07.2017 - 14:54
fonte

5 risposte

43

I sindacati discriminati brilla davvero in combinazione con la corrispondenza del modello, in cui si seleziona un comportamento diverso a seconda dei casi. Ma questo schema è fondamentalmente antitetico ai puri principi OO.

In OO puro, le differenze di comportamento dovrebbero essere definite dai tipi (oggetti) stessi e incapsulate. Quindi l'equivalenza alla corrispondenza del modello sarebbe quella di chiamare un singolo metodo sull'oggetto stesso, che viene quindi sovraccaricato dai sottotipi in questione per definire un comportamento diverso. Ispezionare il tipo di un oggetto dall'esterno (che è ciò che fa la corrispondenza del modello) è considerato un antipattern.

La differenza fondamentale è che i dati e il comportamento sono separati nella programmazione funzionale, mentre i dati e il comportamento sono incapsulati insieme in OO.

Questa è la ragione storica. Un linguaggio come C # si sta sviluppando da un classico linguaggio OO a un linguaggio multi-paradigma incorporando sempre più funzionalità.

    
risposta data 07.07.2017 - 15:47
fonte
33

Avendo programmato in Pascal e Ada prima di apprendere la programmazione funzionale, non associo le unioni discriminate con la programmazione funzionale.

I sindacati discriminati sono in qualche modo il doppio dell'ereditarietà. Il primo consente di aggiungere facilmente operazioni su un set fisso di tipi (quelli dell'unione) e l'ereditarietà consente di aggiungere facilmente tipi con un insieme fisso di operazioni. (Come aggiungere facilmente entrambi è chiamato il problema dell'espressione , che è un problema particolarmente difficile per le lingue con un sistema di tipi statici .)

Data l'enfasi di OO sui tipi e la doppia enfasi della programmazione funzionale sulle funzioni, i linguaggi di programmazione funzionale hanno un'affinità naturale per i tipi di unione e offrono strutture sintattiche per facilitarne l'uso.

    
risposta data 07.07.2017 - 16:04
fonte
7

Le tecniche di programmazione imperative, spesso utilizzate in OO, si basano spesso su due modelli:

  1. Avvia o genera un'eccezione,
  2. Restituisce null per indicare "nessun valore" o errore.

Il paradigma funzionale in genere evita entrambi, preferendo restituire un tipo composto che indica il motivo / valore di successo / errore / nessun valore.

I sindacati discriminati si adattano al conto di questi tipi di composti. Ad esempio, in prima istanza potresti restituire true o una struttura dati che descrive l'errore. Nel secondo caso, un'unione che contiene un valore, o none , nil ecc. Il secondo caso è così comune, che molti linguaggi funzionali hanno un tipo "forse" o "opzione" incorporato per rappresentare quel valore / nessuna unione.

Passando a uno stile funzionale con, ad esempio, C #, troverai rapidamente la necessità di questi tipi di composti. void/throw e null non si sentono corretti con tale codice. E i sindacati discriminati (DU) si adattano bene al conto. Così ti sei trovato a volere loro, proprio come molti di noi hanno.

La buona notizia è che ci sono un sacco di librerie là fuori che i DU modello in es. C # (dai un'occhiata al mio Succinc < T > libreria per esempio).

    
risposta data 07.07.2017 - 15:10
fonte
1

I tipi di somma sarebbero generalmente meno utili nei linguaggi OO tradizionali poiché stanno risolvendo un tipo simile di problema alla sottotipizzazione OO. Un modo per vederli è che entrambi gestiscono il sottotipo ma OO è open i.e. si possono aggiungere sottotipi arbitrari a un tipo genitore e i tipi di somma sono closed i, uno determina in anticipo quali sottotipi sono validi.

Ora, molti linguaggi OO combinano sottotipi con altri concetti come strutture ereditate, polimorfismo, tipizzazione di riferimento, ecc. per renderli generalmente più utili. Una conseguenza è che tendono ad essere più lavoro da impostare (con classi e costruttori e quant'altro), quindi tendono a non essere usati per cose come Result se Option s e così via fino a quando la tipizzazione generica diventa comune.

Direi anche che l'attenzione sulle relazioni del mondo reale che molte persone hanno imparato quando hanno iniziato la programmazione OO, ad es. Dog isa Animal, significa che l'intero è un risultato o errore isa Il risultato sembra un po 'alieno. Sebbene le idee siano abbastanza simili.

Per quanto riguarda il motivo per cui i linguaggi funzionali potrebbero preferire la digitazione chiusa per l'apertura della digitazione, una possibile ragione è che tendono a preferire la corrispondenza del modello. Questo è utile per il polimorfismo di funzione, ma funziona anche molto bene con i tipi chiusi, in quanto il compilatore può controllare staticamente che l'abbinamento copre tutti i sottotipi. Questo può rendere il linguaggio più coerente anche se non credo che ci sia alcun beneficio inerente (potrei sbagliarmi).

    
risposta data 07.07.2017 - 16:13
fonte
-3

Swift utilizza felicemente i sindacati discriminanti, tranne che li chiama "enum". Le enumerazioni sono una delle cinque categorie fondamentali di oggetti in Swift, che sono classi, struct, enum, tuple e closure. Gli optionals Swift sono enumerazioni che sono unioni discriminanti e sono assolutamente essenziali per qualsiasi codice Swift.

Quindi la premessa che "discriminare le unioni sono associate alla programmazione funzionale" è sbagliata.

    
risposta data 08.07.2017 - 21:24
fonte

Leggi altre domande sui tag