2015-04-16 18 views
8

Mi sono imbattuto recentemente in un pezzo di codice che utilizzava lo otherwise di Haskell per associare il modello a un elenco. Questo mi ha colpito come strano, dal momento che:Haskell's `otherwise` è un sinonimo di` _`?

ghci> :t otherwise 
otherwise :: Bool 

Così, ho provato la seguente:

ghci> case [] of otherwise -> "!?" 
"!?" 

Ho provato anche con diversi altri modelli di diversi tipi e con -XNoImplicitPrelude acceso (per rimuovere otherwise da scope), e funziona ancora. Questo dovrebbe succedere? Dove è documentato?

+8

Nel preludio, definisce 'altrimenti = True'. Usandolo in un pattern match si limita a dare ombra a questa definizione, introducendo una nuova variabile locale che viene chiamata anche 'altrimenti'. Un esempio simile è il "caso" che lo shadowing può confondere "of (==) ->" Y'know, "++ (==)', che restituisce "" Sai, lo shadowing può confondere "'. – AndrewC

+6

Proprio perché nessuno lo ha ancora detto, 'altrimenti' dovrebbe essere usato come espressione di guardia, non come modello. 'caso ... di pat | ... -> ... | altrimenti -> ... 'Ora la sua definizione come' True' è importante. –

+0

@AndrewC, ottimo esempio! – luqui

risposta

16

Non è equivalente a _, è equivalente a qualsiasi altro identificatore. Ciò significa che se un identificatore viene utilizzato come modello in Haskell, il modello corrisponde sempre e il valore corrispondente è associato a quell'identificatore (a differenza di _ dove corrisponde sempre, ma il valore corrispondente viene scartato).

Giusto per essere chiari: l'identificatore otherwise non è speciale qui. Il codice potrebbe anche essere stato x -> "!?". Inoltre, poiché l'associazione non viene mai effettivamente utilizzata, sarebbe più logico utilizzare _ per evitare un avviso di "identificatore non utilizzato" e per rendere evidente al lettore che il valore non ha importanza.

+5

'caso [] altrimenti -> (altrimenti,"!? ")' Is '([],"!? ")' È un esempio che mostra come funziona il binding in questo caso. – Guvante

+0

Grazie! Quindi è solo un'altra variabile. Avrei dovuto saperlo ... * sbatte delicatamente la testa sul muro ripetutamente *. – YellPika

+1

Ricorda semplicemente 'altrimenti = True'. Alcune persone usano anche 'True' invece di' altrimenti' nel loro codice che a volte si legge in modo strano ma evita anche l'associazione involontaria. –

9

Proprio perché nessuno lo ha ancora detto, altrimenti dovrebbe essere usato come espressione di guardia, non come modello. caso ... di pat | ... -> ... | altrimenti -> ... Ora la sua definizione come Vero è importante. - Reid Barton

Un esempio:

fact n acc 
    | n == 0 = acc 
    | otherwise = fact (n-1) $! (acc * n) 

Dal otherwise è True, che seconda guardia sarà sempre successo.

Si noti che l'utilizzo di otherwise in un modello (al contrario di una guardia) può confondere le persone. Avverrà anche un avviso di ombreggiatura del nome se GHC viene eseguito con gli avvisi appropriati abilitati.

Problemi correlati