Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Warning on specialisations when compiling Haskell Code with ghc

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?

like image 390
Tim Perry Avatar asked May 05 '11 20:05

Tim Perry


1 Answers

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

like image 125
Don Stewart Avatar answered Sep 28 '22 06:09

Don Stewart