Prima una breve deviazione della terminologia: chiamerei entrambi questi "pattern matching". Non sono sicuro che esista un termine valido per distinguere la corrispondenza del modello, caso per caso e corrispondenza modello, tramite definizione multipla.
La distinzione tecnica tra i due è piuttosto leggera. Puoi verificare tu stesso chiedendo a GHC di scaricare il core che genera per le due funzioni, usando il flag -ddump-simpl
. Ho provato questo a pochi diversi livelli di ottimizzazione, e in tutti i casi le uniche differenze nel Core erano i nomi. (A proposito, se qualcuno conosce un buon programma "semantic diff" per Core - che sa come minimo l'equivalenza alfa - sono molto interessato a sentirlo!)
Ci sono alcuni piccoli trucchi per fare attenzione, però. Ci si potrebbe chiedere se il seguente è anche equivalente:
{-# LANGUAGE LambdaCase #-}
lastButOne = \case
[] -> error "Empty List"
(x:[]) -> error "Only One Element"
(x:[x2]) -> x
(x:xs) -> lastButOneCase xs
In questo caso, la risposta è sì. Ma considerare questo aspetto simile uno:
-- ambiguous type error
sort = \case
[] -> []
x:xs -> insert x (sort xs)
Tutto ad un tratto questo è un CAF typeclass-polimorfico, e così via vecchie GHCs In tal modo, la restrizione monomorfismo e causare un errore, mentre la versione superficialmente identico a un argomento esplicito non lo fa:
-- this is fine!
sort [] = []
sort (x:xs) = insert x (sort xs)
l'altra differenza minore (che ho dimenticato - grazie a Thomas DuBuisson per avermelo ricordato) è nella gestione di clausole WHERE. Dal momento che le clausole sono collegate ai siti vincolanti, non possono essere condivise tra più equazioni ma possono essere condivise in più casi.Per esempio:
-- error; the where clause attaches to the second equation, so
-- empty is not in scope in the first equation
null [] = empty
null (x:xs) = nonempty
where empty = True
nonempty = False
-- ok; the where clause attaches to the equation, so both empty
-- and nonempty are in scope for the entire case expression
null x = case x of
[] -> empty
x:xs -> nonempty
where
empty = True
nonempty = False
Si potrebbe pensare che questo significa che si può fare qualcosa con le equazioni che non si può fare con espressioni case, vale a dire, hanno significati diversi per lo stesso nome a due equazioni, come questo:
null [] = answer where answer = True
null (x:xs) = answer where answer = False
Tuttavia, dal momento che i modelli di case
espressioni sono siti di legame, questo può essere emulato in case
espressioni così:
null x = case x of
[] -> answer where answer = True
x:xs -> answer where answer = False
Se la clausola where
è collegata al modello case
o all'equazione dipende dal rientro, ovviamente.
Preferirei quello con due righe più corte. – Bergi
Le espressioni del caso non utilizzano lo stesso abbinamento di pattern, solo all'interno di un diverso costrutto sintattico? – 9000
Un'espressione case può essere incorporata in un'altra espressione, non necessariamente la prima di una definizione di funzione. Suppongo che le dichiarazioni di funzioni multiple con pattern siano solo uno zucchero sintattico sulla seconda forma. – 9000