Sintassi di Haskell per le definizioni dei tipi: perché il segno di uguaglianza?

3

Sono un po 'confuso dalla scelta della sintassi Haskell per le definizioni dei tipi, come in

data Foo = Bar

Vale a dire: il segno di uguaglianza qui significa davvero un'eguaglianza in qualche senso sottile, o è solo una scelta casuale di notazione?

Ad esempio, in

foo x y = bar y x

l'uguaglianza è davvero un'eguaglianza: se questa linea è presente, foo a b e bar b a possono essere usati più o meno in modo intercambiabile nel programma. Tuttavia, data Foo e Bar probabilmente non possono essere usati in modo intercambiabile dopo data Foo = Bar .

Ogni volta che riprendo i miei tentativi di imparare Haskell, sono un po 'confuso da questa sintassi IMO contro-intuitiva e ho bisogno di cercare la documentazione per richiamare i formati di LHS e RHS. Ci sono delle sintassi alternative per le definizioni dei tipi in ogni caso?

    
posta Alexey 29.07.2014 - 15:42
fonte

2 risposte

7

Hai ragione che data Foo (o anche Foo ) e Bar non possono essere usati in modo intercambiabile nel codice Haskell, ma si potrebbe sostenere che le definizioni di tipo, come

data List a = Nil | Cons a (List a)

può essere trasformato in una "equazione" della forma List(a) = 1 + a * List(a) . E puoi iniziare a giocarci come se fosse un'espressione algebrica: l'equazione può essere riscritta come List(a) = 1 / (1-a) , da cui List(a) = 1 + a + a*a + a*a*a + ... . Vedi il documento Sette alberi in uno per un'applicazione spettacolare, o questa domanda SO per molto altro.

Ovviamente è tutto molto bello, ma non ti aiuterà a leggere meglio le dichiarazioni dei dati!

Per questo, potresti prendere in considerazione l'utilizzo di Tipi di dati algebrici generalizzati, alias GADT . Una caratteristica di questi è che i tipi dei costruttori sono esplicitamente enunciati, rendendo chiaro quale sia il nome di ciascun costruttore, quali tipi di argomenti prende e qual è il tipo di risultato. E non usa quel fastidioso = di segno: -)

Il tuo esempio verrebbe scritto come:

data Foo where
    Bar :: Foo

l'esempio di elenco che ho dato sopra sarebbe:

data List a where
    Nil :: List a
    Cons :: a -> List a -> List a

e un equivalente del confuso nome data X = X X X | Y sarebbe:

data X where
    X :: X -> X -> X
    Y :: X

GADT, tuttavia, non sono Haskell standard: sono un'estensione GHC e piuttosto recenti (quindi potrebbero esserci ancora alcuni bug), ma per il tuo scopo di avere una sintassi di definizione del tipo alternativo penso che si adattino bill bene.

    
risposta data 29.07.2014 - 16:48
fonte
5

Foo è un tipo, Bar è un valore. Non ha senso parlare di scambiarli. Piuttosto, il segno di uguaglianza esprime che il tipo Foo consiste precisamente di quei valori sulla destra; né più né meno.

    
risposta data 29.07.2014 - 16:21
fonte

Leggi altre domande sui tag