2015-04-09 30 views
13

ho imparato da chapter 9 of Learn You A Haskell For Great Good cheSi dovrebbe specificare una firma di tipo per principale o no? Perché perché no?

Per convenzione, che facciamo di solito non specificare una dichiarazione di tipo per main.

Per quanto posso dire, questa convenzione è diffusa. Tuttavia, se compilo, utilizzando il flag -Wall, un programma che manca di una firma tipo per main, come ad esempio

-- test.hs 

-- main :: IO() 
main = print (1 :: Int) 

GHC non emettere un avviso:

$ ghc -Wall test.hs 
[1 of 1] Compiling Main    (test.hs, test.o) 

test.hs:2:1: Warning: 
    Top-level binding with no type signature: main :: IO() 
Linking test ... 
$ 

Sono confuso ... Se una firma di tipo per main è davvero superflua, perché -Wall fa in modo che GHC si lamenti quando manca? Ci sono dei buoni motivi (oltre a eliminare questo avviso) per specificare il tipo di main?

+0

La firma del tipo di livello superiore mancante dovrebbe essere un errore. In realtà dovrebbe essere illegale. – Shoe

+4

Illegale come in dovrebbe essere punibile come crimine. Non illegale nella lingua. – Shoe

+1

In particolare, la firma del tipo * esportato * di livello superiore potrebbe essere un errore. Uso molti helper generici che non vengono esportati, non dispongono di documenti pubblici e le loro firme sono più lunghe dei loro corpi. Scriverli non aiuta affatto ed è solo un fastidio. –

risposta

13

Bene, in generale, come chiarisce questo avviso, è sempre una buona idea per dare un binding di livello superiore a un tipo di firma. In realtà, sarebbe più ragionevole dire

Per convenzione, ci si specifica una dichiarazione del tipo tutto .

Certo, in un grande progetto, main si fa una fatica trascurabile, quindi in realtà non ha alcun senso per omettere la firma. Basta scriverlo, per motivi di coerenza.

Tuttavia, anche se Haskell è grande per i progetti adeguatamente strutturati e in realtà c'è una tendenza a scrivere quasi tutto in librerie, è anche sorprendentemente buono come un linguaggio di scripting rapido, per le cose di altre persone scriverebbero in Python o Perl. E in questi casi, in genere non ti interessa molto della sicurezza e della buona documentazione, ecc., Vuoi semplicemente scrivere qualcosa il più conciso possibile che faccia il lavoro. Normalmente non si compilano questi script con -Wall ma li si esegue semplicemente con runhaskell. E siccome gli script hanno sempre bisogno di contenere un numero main (a differenza della maggior parte degli altri file sorgente Haskell), è davvero abbastanza sensato da omettere la firma qui.

sarei ancora il sospetto che la maggior parte dei Haskellers oggi fare scrittura main::IO() anche negli script più semplici, se solo per abitudine.


solo tutto sul primo livello, vale a dire. Le firme locali a volte hanno anche senso, ma spesso ingombrano il codice.

+0

Grazie per il chiarimento. – Jubobs

+0

Anche per i progetti più grandi ha senso abilitare '-fwarn-missing-signatures' e' -Werror', che quindi obbliga 'main' ad avere una signature di tipo. –

+1

@ PetrPudlák In genere utilizzo '-Wall' (che abilita' -fwarn-missing-signatures', credo) in congiunzione con '-Werror'. – Jubobs

8

In realtà è una buona idea di scrivere una firma tipo per main, altrimenti se si ottiene troppo di fantasia cercando di scrivere le cose in forma libera-punto, si può finire con main di tipo IO (IO()).Questo è accettato (lo standard della lingua dice main deve solo avere un qualche tipo di modulo IO a) ma l'azione "IO interno" che è il risultato di main verrà semplicemente scartata, il che non è quasi certamente quello che volevi (probabilmente volevi a join it).

+0

Interessante. Potresti aggiungere un link dove, nello standard, hai letto che * 'main' deve solo avere un qualche tipo di modulo' IO a' *? – Jubobs

+0

@Jubobs: vedere il secondo paragrafo di https://www.haskell.org/onlinereport/haskell2010/haskellch5.html#x11-980005 –

+0

Spot on. Grazie. – Jubobs