Предупреждение о специализациях при компиляции кода Haskell с помощью ghc

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

$ ghc --make -O2 -Стена -fforce-recomp

[1 из 1] Компиляция Main ( isPrimeSmart.hs, isPrimeSmart.o ) SpecConstr Function `$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

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


person Tim Perry    schedule 05.05.2011    source источник


Ответы (1)


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

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


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

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

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

person Don Stewart    schedule 05.05.2011
comment
Я понимаю. Моя конкретная проблема заключается в том, что я пытаюсь отправить это в SPOJ, и он говорит, что у меня есть ошибка компиляции. Есть ли способ обойти это? Могу ли я изолировать проблемный код и переписать его, чтобы избежать этой проблемы? SPOJ использует ghc 10.4.2. - person Tim Perry; 06.05.2011
comment
Можно ли использовать -w (подавить предупреждения) вместо -Wall? Например. в файле {-# OPTIONS_GHC -w #-}. В качестве альтернативы увеличьте порог, например. -fspec-constr-count=16 - person Don Stewart; 06.05.2011
comment
Если я уберу флаг -O2, то предупреждений не будет. Время увеличивается с 6,5 до 10,5 секунд в моем тестовом файле, и я не ограничиваю время в SPOJ. - person Tim Perry; 06.05.2011
comment
Я предполагаю, что если мой дизайн кода, вероятно, является корневой проблемой. Некоторые онлайн-ответы требуют гораздо меньше времени и памяти, чем я. Вернуться к доске для рисования. Спасибо за вашу помощь. Если вы опубликуете свой комментарий о -w в качестве ответа, я отмечу его принятым. - person Tim Perry; 06.05.2011
comment
{-# OPTIONS_GHC -fspec-constr-count=16 -O2 #-} использует 5,8 секунды для моего тестового файла, а {-# OPTIONS_GHC -w #-} использует 10,5 секунды. Таким образом, -fspec-constr-count=16 определенно предпочтительнее. Спасибо за помощь. - person Tim Perry; 06.05.2011