ero tanto sonno che ho scritto il seguente codice (modificato per mostrare solo la confusione):Haskell: Perché non vi è alcuna mancata corrispondenza di tipo (e perché viene compilata)?
fac s = take 10 [s, s `mod` 1 ..]
maxFactor x = if (s == [])
then x
else head <-- this should be 'head x' instead of just 'head'
where s = fac x
Tuttavia, questo carico in ghci (e compila) bene. Quando ho eseguito maxFactor 1
, si lamenta (ovviamente):
<interactive>:0:1:
No instance for (Integral ([a0] -> a0))
arising from a use of `maxFactor'
Possible fix:
add an instance declaration for (Integral ([a0] -> a0))
In the expression: maxFactor 1
In an equation for `it': it = maxFactor 1
<interactive>:0:11:
No instance for (Num ([a0] -> a0))
arising from the literal `1'
Possible fix: add an instance declaration for (Num ([a0] -> a0))
In the first argument of `maxFactor', namely `1'
In the expression: maxFactor 1
In an equation for `it': it = maxFactor 1
Tuttavia, non capisco questo comportamento:
fac
's tipo è:
fac :: Integral a => a -> [a]
mentre maxFactor
' s tipo è:
maxFactor :: Integral ([a] -> a) => ([a] -> a) -> [a] -> a
Questo non significa e seguente:
- il primo ingresso
fac
deve essere di typeclassIntegral
(ad esempio,fac 10
); - in quanto nella definizione di
maxFactor
, c'èfac x
, x deve essere anche di typeclassIntegral
, in tal modo, il tipomaxFactor
s' sarebbe cominciare con qualcosa di similemaxFactor :: (Integral a) => a ->
... poi qualcosa d'altro? Tuttavia, se questo è il caso, allora perché questo codice viene compilato poiché il rendimento dimaxFactor
può esserex
ohead
, che quando si segue questa linea di ragionamento, non ha lo stesso tipo?
Cosa mi manca qui?
Grazie per eventuali ingressi in anticipo!
Questo tipo di problema può presentarsi in un modo molto più semplice. Sospetto (ma non sono esperto) che possa accadere ogni volta che il correttore di tipi non può ridurre sufficientemente un'espressione. Ad esempio, foo x = 1 + x; bar = foo head - fallirà, ma foo x = 1 + x; bar x = foo head - verrà compilato. – Sarah
@Sarah: l'esempio fornito non digita a causa della limitazione del monomorfismo; se aggiungete il pragma, significa che c'è un piccolo problema: GHCi digita 'Num ([a] → a) ⇒ [a] → a' e non puoi dichiarare' bar' con questo tipo, avresti bisogno di FlexibleContexts per quello). – Vitus
Per quello che vale, se compili con '-Wall' (o aggiungilo alle tue opzioni ghci predefinite, in modo che ghci" compili "con' -Wall') riceverai un avviso perché non hai inserito un tipo firma su 'maxFactor'. Quindi, presumibilmente, scriverai 'maxFactor :: Integral a => a -> a' e non riuscirà a compilare. – MatrixFrog