编译Haskell代码时使用ghc时特定性的警告提示

7
当我尝试编译以下代码时,出现了以下错误: $ 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
以下是我的代码:
{-# 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

这些只是(烦人的)警告,表示 GHC 可以进一步对您的代码进行特殊化,如果您确实希望这样做。未来版本的 GHC 可能不会默认发出此数据,因为您无法对其进行任何操作。

它们是无害的,不是错误。不要担心它们。


要直接解决问题,您可以使用 -w(抑制警告)代替 -Wall

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

或者,增加特殊化阈值将使警告消失,例如 -fspec-constr-count=16


我明白了。我的问题是,我试图将这个提交到SPOJ,但它显示我有编译错误。有什么解决方法吗?我能够隔离出有问题的代码并重新编写以避免这个问题吗?SPOJ使用ghc 10.4.2。 - Tim Perry
1
你可以使用-w(抑制警告)代替-Wall吗?例如,在文件中 {-# OPTIONS_GHC -w #-}。或者,增加阈值,例如 -fspec-constr-count=16 - Don Stewart
如果我去掉-O2标志,那么就没有警告了。在我的测试文件上,时间从6.5秒增加到10.5秒,我无法满足SPOJ的时间限制。 - Tim Perry
我猜我的代码设计可能是根本问题。在线上的一些答案使用的时间和内存都比我少得多。回到绘图板重新设计。不过还是谢谢你的帮助。如果你把关于“-w”的评论发布为答案,我会把它标记为已接受。 - Tim Perry
2
{-# OPTIONS_GHC -fspec-constr-count=16 -O2 #-}用于我的测试文件使用了5.8秒,而{-# OPTIONS_GHC -w #-}使用了10.5秒。因此,-fspec-constr-count=16显然更优。感谢您的帮助。 - Tim Perry

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接