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