2011-05-05 36 views
7

我在嘗試編譯警告有關編譯Haskell代碼與GHC當特

$ GHC --make -02 -Wall -fforce-recomp

[1 1]編譯時出現以下錯誤主( isPrimeSmart.hs,isPrimeSmart.o) SpecConstr 功能`$ WA {v s2we} [蓋子]」 有兩個呼叫模式,但限制是1 使用-fspec-構造計數= N來設置綁定 使用-dppr-debug查看專業化鏈接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 

我不知道如何解決這一問題的警告。我如何開始?我是否編譯彙編並匹配錯誤?警告甚至意味着什麼?

回答

7

這些只是(惱人的)警告,表明如果您真的想要,GHC可以對您的代碼進行進一步的專業化。未來版本的GHC可能不會默認發佈這些數據,因爲無論如何你都無法做到這一點。

它們是無害的,並不是錯誤。不要擔心他們。


直接解決這個問題,你可以使用-w(抑制警告),而不是-Wall

例如在文件{-# OPTIONS_GHC -w #-}將禁用警告。

或者,增加專門化閾值將使警告消失,例如, -fspec-constr-count=16

+0

我明白了。我特別的問題是我試圖把這個提交給SPOJ,它說我有一個編譯錯誤。有沒有解決的辦法?我可以隔離有問題的代碼並重新編寫它以避免此問題嗎? SPOJ使用ghc 10.4.2。 – 2011-05-05 20:52:46

+1

您可以使用'-w'(取消警告)而不是'-Wall'?例如。在文件'{ - #OPTIONS_GHC -w# - }'中。或者,增加閾值,例如'-fspec-constr-count = 16' – 2011-05-05 20:57:52

+0

如果我取出-O2標誌,那麼就沒有警告。時間從我的測試文件的6.5秒到10.5秒,並且我沒有在SPOJ上設置時間限制。 – 2011-05-05 21:02:37