2013-08-16 12 views
14

Chcę związek wzrost w ciągu roku, ale nie dbam o punkty po przecinku, więc próbowałemKonwersja Integer podwojeniu w Haskell

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

Problem polega na tym, że typ (floor . (*1.1)) jest Double -> Integer, natomiast typ oczekiwany przez pierwszy argument iteracji to a -> a.

Próbowałem kilka podejść, ale skończyło się wiązanie się w węzłach.

Jakie jest preferowane rozwiązanie do utrzymywania spójności typów liczbowych w różnych aplikacjach?

+4

Nie można kontynuować zaokrąglania wyników pośrednich i mam nadzieję, że otrzymam poprawną odpowiedź na końcu. Dlaczego nie przenieść 'podłogi' z' iterate' i zrobić 'map floor. weź 52 $ ... "? – Fixnum

+0

@Fixnum fair point, to było coś, co próbowałem uruchomić w ghci, gdy wpadłem na problem. –

Odpowiedz

18

Zwykłym sposobem konwersji Int do Double jest użycie fromIntegral, która ma typ (Integral a, Num b) => a -> b. Oznacza to, że konwertuje on typ Integral (Int i Integer) na dowolny numeryczny typ b, którego instancją jest.

Twoja sprawa brzmi jak chcesz przekonwertować Double do Int, które polecam dla floor, ale musisz upewnić się, że wejście jest Double. W tym celu można użyć funkcji fromIntegral z

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

Będzie to jednak daje niedokładne wyniki, ponieważ jesteś obcinania na każdym kroku. Sugerowałbym wykonanie

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

Dodam również, że ostatnie wyrażenie będzie nieco szybsze, ponieważ 'fromIntegral' jest wykonywane raz,' (* 1.1) 'jest wciąż powtarzane, a' floor' jest wykonywane tylko tyle razy, ile to konieczne, chociaż można by argumentować do transpozycji 'map floor' i' take 52'. – bheklilr

+3

Równoważnie napisany jako: 'weź 52. podłoga mapy. iteruj (* 1.1). fromIntegral $ 100' – Davorak