2011-05-05 13 views
7

me sale el siguiente error al intentar compilarde advertencia en especializaciones al compilar código Haskell con GHC

$ GHC --make -O2 -Wall -fforce-ReComp

[1 de 1] Compilación principales ( isPrimeSmart.hs, isPrimeSmart.o) SpecConstr función `wa $ {v} s2we [tapa]' tiene dos patrones de llamada, pero el límite es de 1 uso -fspec-construction: count = n para establecer el obligado Utilice -dppr-debug para ver las especializaciones Vinculación isPrimeSmart ...

Mi código es:

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

no tengo ni idea de cómo solucionar esta advertencia. ¿Como empiezo? ¿Puedo compilar para ensamblar y unir el error? ¿Qué significa la advertencia?

Respuesta

7

Estas son solo (molestas) advertencias, lo que indica que GHC podría hacer más especializaciones a su código si realmente lo desea. Es probable que las versiones futuras de GHC no emitan estos datos de forma predeterminada, ya que no hay nada que puedas hacer al respecto de todos modos.

Son inofensivos, y no son errores. No te preocupes por ellos


Para abordar directamente el problema, puede utilizar -w (suprimir advertencias) en lugar de -Wall.

E.g. en un archivo {-# OPTIONS_GHC -w #-} desactivará las advertencias.

De forma alternativa, al aumentar el umbral de especialización, la advertencia desaparecerá, p. -fspec-constr-count=16

+0

Ya veo. Mi problema particular es que trato de enviar esto a SPOJ y dice que tengo un error de compilación. ¿Hay alguna forma de evitar esto? ¿Puedo aislar el código ofensivo y volver a escribirlo para evitar este problema? SPOJ usa ghc 10.4.2. –

+1

¿Se puede usar '-w' (suprimir advertencias) en lugar de' -Wall'? P.ej. en un archivo '{- # OPTIONS_GHC -w # -}'. Alternativamente, aumente el umbral, p. '-fspec-constr-count = 16' –

+0

Si saco el indicador -O2, entonces no hay advertencias. El tiempo va de 6.5 segundos a 10.5 segundos en mi archivo de prueba y no hago el límite de tiempo en SPOJ. –

Cuestiones relacionadas