2011-07-14 13 views

Odpowiedz

37

Korzystanie fromIntegral:

Prelude> let x = 5::Int 
Prelude> sqrt (fromIntegral x) 
2.23606797749979 

oba Int i Integer są przypadki Integral:

  • fromIntegral :: (Integral a, Num b) => a -> b ma swoje Int (który jest instancją Integral) i "robi" to Num.

  • sqrt :: (Floating a) => a -> a oczekuje Floating i Floating dziedziczą z Fractional, która dziedziczy z Num, więc można bezpiecznie przejść do sqrt wynik fromIntegral

myślę, że zajęcia diagram w Haskell Wikibook jest bardzo przydatne w takich przypadkach.

+1

Czy 'sqrt (fromIntegral x)' może być również zapisany jako 'sqrt $ fromIntegral x'? – rzetterberg

+0

Tak, rzeczywiście, może, ponieważ jawna aplikacja ($) nie wiąże się tak ściśle jak niejawna aplikacja. – Edward

+0

tak! a także '(sqrt. fromIntegral) x' – MarcoS

10

Pamiętaj, że aplikacja wiąże się szczelniej niż jakikolwiek inny operator. Obejmuje to kompozycję. Co chcesz jest

sqrt $ fromIntegral x 

Następnie

fromIntegral x 

zostaną najpierw ocenione, ponieważ ukryte aplikacji (przestrzeń) wiąże mocniej niż jednoznacznego wniosku ($).

Alternatywnie, jeśli chcesz zobaczyć, jak kompozycja będzie działać:

(sqrt . fromIntegral) x 

Nawiasy upewnić się, że operator skład ocenia najpierw, a następnie otrzymaną funkcją jest po lewej stronie aplikacji.

33

Być może chcesz, aby wynik był również Int?

isqrt :: Int -> Int 
isqrt = floor . sqrt . fromIntegral 

Możesz zastąpić floor z ceiling lub round. (BTW, ta funkcja ma bardziej ogólny typ niż ten, który dałem.)

+1

ghc ostrzega o tym, ponieważ nie wie, jakiego typu należy użyć między 'fromIntegral' i' floor' (może to być 'Double',' Float', itp.). Aby naprawić: 'isqrt x = floor.sqrt $ (fromIntegral x :: Float) ', które jest mniej eleganckie :( –

+0

W każdym razie lubię to, nie ostrzegam o GHC 8. –