show - Why does Haskell want this function's argument to have the type classes (RealFrac x, Integral x) when it only needs to be Integral x? -
i'm trying write code complete factorization of integer trial division. code seems ought work:
findafact :: integral x => x -> x findafact x = searchints [2, 3..] x searchints (int:ints) div | div `mod` int == 0 = int | otherwise = searchints ints div completefacts :: integral x => x -> [x] completefacts x = tryforfact [] x tryforfact fs x = if x == 1 fs else let fact = findafact x in tryforfact (fact:fs) (floor ((fromintegral x) / fact))
but if try compile following error:
could not deduce (realfrac x) arising use of 'tryforfact' context (integral x) bound type signature completefacts :: integral x => x -> [x] @ 5.hs:26:18-39 possible fix: add (realfrac x) context of type signature completefacts :: integral x => x -> [x] in expression: tryforfact [] x in equation 'completefacts': completefacts x = tryforfact [] x tryforfact fs x = if x == 1 fs else let ... in tryforfact (fact : fs) (floor ((fromintegral x) / fact))
if remove type signature completefacts
, try loading ghci, interpreter loads file , supplies type signature (realfrac x, integral x ) => x -> [x]
completefacts
, complains when try use completefacts
there's no way show
because type ambiguous in context of show
. makes sense me because seems there clear way display x realfrac
or integral
, not both.
this seems offending code:
... in tryforfact (fact:fs) (floor ((fromintegral x) / fact))
i'm confused because i'd imagine passing x through fromintegral
, passing result of division floor
give me integral
back. don't see why haskell still thinks x needs have type class realfrac
. why haskell insist on this, , how can rewrite completefacts
x can integral
?
thanks!
it's because didn't convert fact
realfrac
before doing division:
in tryforfact (fact:fs) (floor (fromintegral x / fromintegral fact))
you've said fact = findafact x
, has type integral x => x
, you're using in division /
, thinks needs satisfy both integral
, realfrac
.
what better use div
instead (i've cleaned code little bit it's easier read , aren't shadowing existing binding x
):
completefacts :: integral x => x -> [x] completefacts x = tryforfact [] x tryforfact fs 1 = fs tryforfact fs y = let fact = findafact y in tryforfact (fact:fs) (y `div` fact)
Comments
Post a Comment