I get the following error when trying to compile
$ ghc --make -O2 -Wall -fforce-recomp
[1 of 1] Compiling Main ( isPrimeSmart.hs, isPrimeSmart.o ) SpecConstr Function `$wa{v s2we} [lid]' has two call patterns, but the limit is 1 Use -fspec-constr-count=n to set the bound Use -dppr-debug to see specialisations Linking isPrimeSmart ...
My code is:
{-# OPTIONS_GHC -O2 -optc-O2 #-}
import qualified Data.ByteString.Lazy.Char8 as StrL -- StrL is STRing Library
import Data.List
-- read in a file. First line tells how many cases. Each case is on a separate
-- line with the lower an upper bounds separated by a space. Print all primes
-- between the lower and upper bound. Separate results for each case with
-- a blank line.
main :: IO ()
main = do
let factors = takeWhile (<= (ceiling $ sqrt (1000000000::Double))) allPrimes
(l:ls) <- StrL.lines `fmap` StrL.getContents
let numCases = readInt l
let cases = (take numCases ls)
sequence_ $ intersperse (putStrLn "") $ map (doLine factors) cases
-- get and print all primes between the integers specified on a line.
doLine :: [Integer] -> StrL.ByteString -> IO ()
doLine factors l = mapM_ print $ primesForLine factors l
---------------------- pure code below this line ------------------------------
-- get all primes between the integers specified on a line.
primesForLine :: [Integer] -> StrL.ByteString -> [Integer]
primesForLine factors l = getPrimes factors range
where
range = rangeForLine l
-- Generate a list of numbers to check, store it in list, and then check them...
getPrimes :: [Integer] -> (Integer, Integer) -> [Integer]
getPrimes factors range = filter (isPrime factors) (getCandidates range)
-- generate list of candidate values based on upper and lower bound
getCandidates :: (Integer, Integer) -> [Integer]
getCandidates (propStart, propEnd) = list
where
list = if propStart < 3
then 2 : oddList
else oddList
oddList = [listStart, listStart + 2 .. propEnd]
listStart = if cleanStart `rem` 2 == 0
then cleanStart + 1
else cleanStart
cleanStart = if propStart < 3
then 3
else propStart
-- A line always has the lower and upper bound separated by a space.
rangeForLine :: StrL.ByteString -> (Integer, Integer)
rangeForLine caseLine = start `seq` end `seq` (start, end)
where
[start, end] = (map readInteger $ StrL.words caseLine)::[Integer]
-- read an Integer from a ByteString
readInteger :: StrL.ByteString -> Integer
readInteger x =
case StrL.readInteger x of Just (i,_) -> i
Nothing -> error "Unparsable Integer"
-- read an Int from a ByteString
readInt :: StrL.ByteString -> Int
readInt x =
case StrL.readInt x of Just (i,_) -> i
Nothing -> error "Unparsable Int"
-- generates all primes in a lazy way.
allPrimes :: [Integer]
allPrimes = ps (2:[3,5 .. ])
where
ps (np:candidates) = -- np stands for New Prime
np : ps (filter (\n -> n `rem` np /= 0) candidates)
ps [] = error "this can't happen but is shuts up the compiler"
-- Check to see if it is a prime by comparing against the factors.
isPrime :: [Integer] -> Integer -> Bool
isPrime factors val = all (\f -> val `rem` f /= 0) validFactors
where
validFactors = takeWhile (< ceil) factors
ceil = ((ceiling $ sqrt $ ((fromInteger val)::Double))) :: Integer
I have no idea how to fix this warning. How do I start? Do I compile to assembly and match the error up? What does the warning even mean?
These are just (annoying) warnings, indicating that GHC could do further specializations to your code if you really want to. Future versions of GHC will likely not emit this data by default, since there's nothing you can do about it anyway.
They are harmless, and are not errors. Don't worry about them.
To directly address the problem, you can use -w
(suppress warnings) instead of -Wall
.
E.g. in a file {-# OPTIONS_GHC -w #-}
will disable warnings.
Alternately, increasing the specialization threshold will make the warning go away, e.g. -fspec-constr-count=16
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With