Jak mogę uzyskać sqrt
od Int
.Uzyskaj sqrt od Int w Haskell
staram tak:
sqrt . fromInteger x
Ale się błąd z kompatybilności typów.
Jak mogę uzyskać sqrt
od Int
.Uzyskaj sqrt od Int w Haskell
staram tak:
sqrt . fromInteger x
Ale się błąd z kompatybilności typów.
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.
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.
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.)
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 :( –
W każdym razie lubię to, nie ostrzegam o GHC 8. –
Czy 'sqrt (fromIntegral x)' może być również zapisany jako 'sqrt $ fromIntegral x'? – rzetterberg
Tak, rzeczywiście, może, ponieważ jawna aplikacja ($) nie wiąże się tak ściśle jak niejawna aplikacja. – Edward
tak! a także '(sqrt. fromIntegral) x' – MarcoS