簡體   English   中英

無法將預期類型`Bool'與實際類型`IO Bool'匹配

[英]Couldn't match expected type `Bool' with actual type `IO Bool'

我正在嘗試編寫素數生成器並使用MillerRabin公式檢查數字是否為素數,然后將數字返回給我。 這是我的代碼如下:

primegen :: Int -> IO Integer
primegen bits =
    fix $ \again -> do
        x <- fmap (.|. 1) $ randomRIO (2^(bits - 1), 2^bits - 1)
        if primecheck x then return x else again

primesTo100 = [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97]

powerMod :: (Integral a, Integral b) => a -> a -> b -> a
powerMod m _ 0 =  1
powerMod m x n | n > 0 = join (flip f (n - 1)) x `rem` m where
  f _ 0 y = y
  f a d y = g a d where
    g b i | even i    = g (b*b `rem` m) (i `quot` 2)
          | otherwise = f b (i-1) (b*y `rem` m)

witns :: (Num a, Ord a, Random a) => Int -> a -> IO [a]
witns x y = do
     g <- newStdGen 
     let r = [9080191, 4759123141, 2152302898747, 3474749600383, 341550071728321]
         fs = [[31,73],[2,7,61],[2,3,5,7,11],[2,3,5,7,11,13],[2,3,5,7,11,13,17]]
     if  y >= 341550071728321
      then return $ take x $ randomRs (2,y-1) g
       else return $ snd.head.dropWhile ((<= y).fst) $ zip r fs

primecheck :: Integer -> IO Bool
primecheck n | n `elem` primesTo100 = return True
                     | otherwise = do
    let pn = pred n
        e = uncurry (++) . second(take 1) . span even . iterate (`div` 2) $ pn
        try = return . all (\a -> let c = map (powerMod n a) e in
                                  pn `elem` c || last c == 1)
    witns 100 n >>= try

我不明白IO Bool會發生什么。 我收到以下錯誤...

 Couldn't match expected type `Bool' with actual type `IO Bool'
 In the return type of a call of `primecheck'
 In the expression: primecheck x
 In a stmt of a 'do' block: if primecheck x then return x else again

如果我將IO Bool改為普通的Bool,他們會給我這個:

Couldn't match expected type `Bool' with actual type `m0 a0'

謝謝你的幫助! 我很感激。

if primecheck x then return x else again

無效,因為primecheck x返回IO Bool類型的值。 你想用編號或類似的東西對monad進行排序:

primecheck x >>= (\val -> if val then return x else again)

由於primecheck返回IO Bool ,當你在primegen調用它時,你需要對它進行排序,而不是像純函數一樣調用它。

primegen :: Int -> IO Integer
primegen bits =
    fix $ \again -> do
        x <- fmap (.|. 1) $ randomRIO (2^(bits - 1), 2^bits - 1)
        success <- primecheck x
        if success then return x else again

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM