Предупреждение о специализациях при компиляции кода на Haskell с помощью ghc - PullRequest
7 голосов
/ 06 мая 2011

Я получаю следующую ошибку при попытке скомпилировать

$ ghc --make -O2 -Wall -fforce-Recomp

[1 из 1] Компиляция Main ( isPrimeSmart.hs, isPrimeSmart.o) SpecConstr Функция `$ wa {v s2we} [lid] ' имеет две модели вызовов, но ограничение составляет 1 Используйте -fspec-constr-count = n, чтобы установить границу Используйте -dppr-debug для просмотра специализаций. Linking isPrimeSmart ...

Мой код:

{-# 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

Понятия не имею, как исправить это предупреждение. Как начать? Скомпилировать в сборку и сопоставить ошибку? Что вообще означает предупреждение?

1 Ответ

7 голосов
/ 06 мая 2011

Это всего лишь (раздражающие) предупреждения, указывающие на то, что GHC может сделать дополнительную специализацию для вашего кода, если вы действительно этого хотите.Будущие версии GHC, скорее всего, не будут отправлять эти данные по умолчанию, поскольку в любом случае вы ничего не можете с этим поделать.

Они безвредны и не являются ошибками.Не беспокойся о них.


Для непосредственного решения проблемы вы можете использовать -w (подавление предупреждений) вместо -Wall.

Например, в файле {-# OPTIONS_GHC -w #-} отключатся предупреждения.

Альтернативно, увеличение порога специализации приведет к исчезновению предупреждения, например, -fspec-constr-count=16

...