2010-05-18 14 views
18

Considerate questo esempio:Haskell: Inadempiente vincoli per digitare

applyKTimes :: Integral i => i -> (a -> a) -> a -> a 
applyKTimes 0 _ x = x 
applyKTimes k f x = applyKTimes (k-1) f (f x) 

applyThrice :: (a -> a) -> a -> a 
applyThrice = applyKTimes 3 

Il 3 in applyThrice è in default da GHC a un Integer come mostrato durante la compilazione con -Wall:

Warning: Defaulting the following constraint(s) to type 'Integer' 
     'Integral t' 
      arising from a use of 'applyKTimes' 

quindi credo che Integer è il valore predefinito Integral a => a.

  • C'è un modo per definire "tipi predefiniti" anche per altri vincoli?
  • L'utilizzo dei tipi predefiniti è una cattiva pratica? (Che si lamenta quando si utilizza -Wall ..)

risposta

14

Sì, you can, anche se non è così semplice come l'aggiunta di un default per typeclass, e funziona solo per Num e le sue sottoclassi nelle librerie Prelude e standard. La sintassi è default (t1, ..., tn) e solo una di queste dichiarazioni può essere utilizzata per modulo.

L'aggiunta di default (Int), ad esempio, modifica il valore predefinito per Integral nel codice per Int.

Il valore predefinito predefinito di (Integer, Double) non è solo un criterio GHC: è dallo Haskell 98 Report. (GHCi ha extended default rules, tuttavia.)

Questo è il numero a discussion di alcuni dei problemi con il sistema corrente.