2009-12-28 15 views
8

Sto imparando Haskell. Ho creato una funzione che restituisce la tabella di moltiplicazione fino a 'n' nella base 'b'. I numeri sono riempiti con cifre 'w'. Come ultimo passo, voglio calcolare 'w' automaticamente. Perché questo non è compilato?Nessuna istanza per (Floating Int)

-- Number of digits needed for the multiplication table n*n in base 'base' 
nOfDg :: Int -> Int-> Int 
nOfDg n base = 1 + floor (logBase base (n*n)) 

errore:

No instance for (Floating Int) 
    arising from a use of `logBase' at C:\haskel\dgnum.hs:4:24-38 
    Possible fix: add an instance declaration for (Floating Int) 
    In the first argument of `floor', namely `(logBase b (n * n))' 
    In the second argument of `(+)', namely `floor (logBase b (n * n))' 
    In the expression: 1 + floor (logBase b (n * n)) 

risposta

10

logbase prende due parametri che implementano il typeclass galleggiante. Dovrai chiamare da Integrale sui parametri prima di passarli a logBase. Questo compilato per me con 6.10.3:

nOfDg :: Int -> Int-> Int 
nOfDg n base = 1 + floor (logBase (fromIntegral base) (fromIntegral (n*n))) 

Bisogna ricordare che Haskell è fortemente tipizzato, quindi non si può dare per scontato che i parametri Int forniti alla funzione saranno automaticamente costretti ai numeri galleggianti quelle funzioni di registro generalmente prendono.

5

logBase è dichiarato funzionare su tipi a virgola mobile. Int non è un tipo a virgola mobile e vi è no automatic conversion in Haskell. Prova questo:

-- Number of digits needed for the multiplication table n*n in base 'base' 
nOfDg :: Int -> Float -> Int 
nOfDg n base = 1 + floor (logBase base (fromIntegral (n*n))) 
+0

Suppongo che avrete bisogno anche di '(fromIntegral base)'. –

+0

@Jason: non con il tipo Dan ha dato quella funzione, non lo farai. – Chuck

+0

Sì, dipende da come lo vuoi usare. O farlo come se fosse OK cambiare la firma del tipo, o usare la versione di Andy se no. –

3

dal preludio:

logBase :: Floating a => a -> a -> a 

Ciò significa che l'utilizzo di logbase è necessario utilizzare un tipo flottante. Ma Int non è un tipo flottante, e non c'è la conversione automatica per i tipi numerici, in modo da avere per convertirlo da Int ad un tipo flottante:

nOfDg n base = 1 + floor (logBase (toEnum base) (toEnum n)) 

la funzione toEnum prendere un int come parametro e restituisce un " Enum "tipo. La parte buona è che Float è un'istanza di Enum, quindi è possibile usarli anche

toEnum :: Enum a => Int -> a 

È necessario leggere/a documentare sulle classi di tipo standard a Haskell per i tipi numerici (Num, frazionale, Integral, galleggiante ...) poiché spesso compaiono nel codice, le conversioni di apprendimento potrebbero essere utili.

Modifica: questo Haskell Wiki Book fornisce un grafico molto utile della relazione tra la classe del tipo di standard, inclusi i tipi numerici.

Problemi correlati