Come sono le classificazioni tipografiche in lingue funzionali diverse dalle interfacce nelle lingue OO?

6

Sto imparando sui paradigmi dei linguaggi funzionali. Quindi ho letto che mentre il polimorfismo del sottotipo è tipico dei linguaggi OO, il polimorfismo parametrico è tipico dei linguaggi funzionali.

Ma mi chiedo se esiste il polimorfismo del sottotipo nei linguaggi funzionali. Il linguaggio funzionale che conosco meglio è Haskell, e so che ci sono dei typeclass in Haskell.

Ho sempre pensato che le classificazioni fossero in qualche modo simili alle interfacce e le interfacce sono il polimorfismo del sottotipo. Per esempio. qui:

data Foo a = Bar a | Baz String
deriving instance Eq a => Eq (Foo a)

Eq è un typeclass che definisce l'operatore (==) . In pratica è come una classe Foo che implementa un'interfaccia Eq .

Quindi quello che sto chiedendo è: questo è considerato sottotipo (o polimorfismo di sottotipo)?

    
posta hgiesel 07.07.2016 - 07:19
fonte

3 risposte

2

Per rispondere alla tua domanda in modo più esplicito: no, questo non è il polimorfismo del sottotipo, e la ragione è semplicemente questa: ogni tipo che ha un'istanza di un typeclass è distinto. Ognuno ha diverse funzioni con (potenzialmente) diverse firme, ad esempio se abbiamo i seguenti tipi:

data First = First String
             deriving Eq
data Second = Second Int
              deriving Eq

questi finiscono con due funzioni completamente distinte:

(==) :: First -> First -> Bool
(==) :: Second -> Second -> Bool

Per essere sottotipi dello stesso tipo, dovrebbero avere firme dei tipi compatibili , cioè dovresti essere in grado di usare o esattamente nelle stesse situazioni, ma non puoi. Se hai un valore con un'istanza Eq , non puoi confrontarlo arbitrariamente con un altro valore a meno che tu non sappia che entrambi hanno lo stesso tipo.

Le classi di tipi sono effettivamente un modo per fare due cose:

  • Specifica dei predicati sui parametri del tipo
  • Consentire la condivisione di nomi di funzioni / operatori tra tipi specificando un modo uniforme di determinare come gestire il nome

Sebbene abbiano similitudini tra le interfacce nell'uso comune, sono molto diverse in modi sottili ma molto importanti.

    
risposta data 07.07.2016 - 12:47
fonte
5

Le istanze delle classi di caratteri sono parametri impliciti che contengono un dizionario di funzioni. Questo li rende diversi dalle interfacce in pochi modi.

Uno è che non è necessaria un'istanza effettiva su cui richiamare le operazioni e che la risoluzione può avvenire a livello di tipo anziché a livello di valore. La classe Read è un esempio:

class Read a where
  read :: String -> a

un'altra differenza è che l'approccio di classe può far rispettare l'uniformità tra i tipi di parametri, mentre le interfacce nascondono il tipo di uno dei parametri (il ricevitore). Dato l'esempio di Eq nella tua domanda, l'approccio dell'interfaccia ti permetterebbe di definire una classe come:

class Dog : IEquatable<Cat> {
    bool Equals(Cat c) { return false }
}

che non puoi fare con l'approccio alla classe di caratteri poiché il tipo a appare solo una volta nella definizione. Molti linguaggi OO definiscono quindi un'altra interfaccia come

interface IEqualityComparer<T> {
    bool Equals(T first, T second);
}

che è simile all'approccio typeclass, tranne che le istanze di questa interfaccia devono essere passate esplicitamente in ogni operazione, mentre le istanze di typeclass vengono passate implicitamente.

    
risposta data 07.07.2016 - 12:34
fonte
2

La più grande differenza è che le classi di tipi sono aperte e le interfacce sono chiuse .

Ciò che intendo è che se hai un tipo di terze parti, se non implementa un'interfaccia, allora sei sfortunato. Puoi estenderlo o adattarlo a un nuovo tipo che può quindi implementare l'interfaccia che desideri.

Se hai qualche tipo di terze parti che non implementa una classe di caratteri, va bene. Devi solo entrare e specificare l'implementazione della classe del tipo per quel tipo di terze parti.

Ciò consente una grande flessibilità durante la progettazione del codice e l'unione di elementi.

    
risposta data 07.07.2016 - 13:45
fonte

Leggi altre domande sui tag