2013-08-16 7 views
14

voglio peggiorare la crescita più di un anno ma non mi importa di punti decimali, così ho provatoConversione Integer al Doppia in Haskell

take 52 $ iterate (floor . (*1.1)) 100 

Il problema è che il tipo di (floor . (*1.1)) è Double -> Integer, mentre la il tipo previsto dal primo argomento di iterazione è a -> a.

Ho provato un paio di approcci, ma ho finito per legarmi in nodi.

Qual è la soluzione preferita per mantenere i tipi numerici coerenti tra le varie applicazioni?

+4

Non è possibile continuare a arrotondare i risultati intermedi e sperare di ottenere una risposta corretta alla fine. Perché non spostare il 'floor' di' iterate' e fare 'map floor. prendere 52 $ ... '? – Fixnum

+0

@Fixnum fair point, era solo qualcosa che ho cercato di eseguire in ghci quando ho incontrato il problema. –

risposta

18

Il modo usuale per convertire un Int in un Double è utilizzare fromIntegral, che ha il tipo (Integral a, Num b) => a -> b. Ciò significa che converte un tipo Integral (Int e Integer) in qualsiasi tipo numerico b, di cui Double è un'istanza.

Il tuo caso suona come si desidera convertire un Double ad un Int, che consiglierei floor per, ma si dovrà fare in modo che l'input è un Double. Per questo, è possibile utilizzare la funzione di fromIntegral con

take 52 $ iterate (floor . (* 1.1) . fromIntegral) 100 

Tuttavia, questo vi darà risultati non accurati, dal momento che si sta troncando ad ogni passo. Suggerirei di fare

take 52 $ map floor $ iterate (* 1.1) $ fromIntegral 100 
+0

Aggiungerò anche che quest'ultima espressione sarà leggermente più veloce dato che 'fromIntegral' viene eseguito una volta,' (* 1.1) 'è ancora ripetuto, e' floor' viene eseguito solo tante volte quanto necessario, anche se potrebbe essere fatto un argomento per trasporre 'map floor' e' take 52'. – bheklilr

+3

Equivalentemente scritto come: 'prendere 52. piano della mappa. iterare (* 1.1). fromIntegral $ 100' – Davorak