When I load the following code in ghci I get a Monomomorphism restriction warning with the suggested fix of
Consider giving ‘pexp’ and ‘nDividedByPExp’ a type signature

17  (nDividedByPExp, pexp) = getPExp' nDividedByP 1
but doing that doesn't solve the problem. I then get the error:
Overloaded signature conflicts with monomorphism restriction
nDividedByPExp :: Integral i => i
Here is the code:
{# OPTIONS_GHC Wall fnowarnincompletepatterns #}
{# LANGUAGE ExplicitForAll, ScopedTypeVariables #}
pfactor :: forall i. Integral i => i > [(i, i)]
 pfactor :: Integral i => i > [(i, i)]
pfactor m =
pf' m [] $ primesUpTo (floorSqrt m)
where
pf' :: Integral i => i > [(i, i)] >[i] > [(i, i)]
pf' n res (p : ps)
 pIsNotAFactor = pf' n res ps
 otherwise = pf' nDividedByPExp ((p, pexp) : res) remainingPrimes
where
(nDividedByP, r) = n `quotRem` p
pIsNotAFactor = r /= 0
 nDividedByPExp, pexp :: Integral i => i
(nDividedByPExp, pexp) = getPExp' nDividedByP 1
 getPExp' :: Integral i => i > i > (i, i)
getPExp' currNDividedByP currExp
 pDoesNotDivideCurrNDividedByP = (currNDividedByP, currExp)
 otherwise = getPExp' q1 (currExp + 1)
where
 q1, r1 :: Integral i => i
(q1, r1) = currNDividedByP `quotRem` p
pDoesNotDivideCurrNDividedByP = r1 /= 0
remainingPrimes = takeWhile (<= floorSqrt nDividedByPExp) ps
floorSqrt :: Integral i => i > i
floorSqrt = undefined
primesUpTo :: Integral i => i > [i]
primesUpTo = undefined
I tried adding the declaration in commented line 16 as suggested but that resulted in an error as I described above.
I've deleted some lines from the actual code to make it simpler. I don't expect the code above to run properly but I do expect it to compile without warnings. I don't understand how to fix the warning I am getting.
When you declare their types as nDividedByPExp, pexp :: Integral i => i
, it'll be treated as nDividedByPExp, pexp :: forall i. Integral i => i
. This i
and the i
declared at the top level will be different types even though you brought the latter to the scope using ScopedTypeVariables
. Also, i
is still polymorphic.
You can declare it as nDividedByPExp, pexp :: i
, where i
refers to the i
at the top level which is bound to a specific type so is monomorphic.