packages feed

Flint2-Examples-0.1.0.0: app/primegen/Main.hs

import Options.Applicative
import Control.Monad
import Control.Monad.State

import Foreign.C.Types
import Foreign.Ptr

import Data.Number.Flint

main = run =<< customExecParser (prefs showHelpOnEmpty) opts where
  opts = info (parameters <**> helper) (
         fullDesc
      <> progDesc "Generate primes."
      <> header "Generate primes.")

run params@(Parameters n count) = do
  prime_iter <- newNPrimes
  if count then do
    (_, (prime_pi, _)) <- runStateT (countPrimes params) (0, prime_iter)
    print prime_pi
  else do
    _ <- runStateT (printPrimes params) prime_iter
    return ()
    
printPrimes :: Parameters -> StateT NPrimes IO ()
printPrimes params@(Parameters n count) = do
  prime_iter <- get
  (_, prime) <- liftIO $ withNPrimes prime_iter n_primes_next
  when (prime < n) $ do
    liftIO $ print prime
    put prime_iter
    printPrimes params

countPrimes :: Parameters -> StateT (Int, NPrimes) IO ()
countPrimes params@(Parameters n count) = do
  (nprimes, prime_iter) <- get
  (_, prime) <- liftIO $ withNPrimes prime_iter n_primes_next
  when (prime < n) $ do
    put (succ nprimes, prime_iter)
    countPrimes params
    
data Parameters = Parameters {
    n :: CULong
  , count :: Bool
} deriving Show

parameters :: Parser Parameters
parameters = Parameters
  <$> argument auto (
      help "n"
   <> metavar "n")
  <*> switch (
      help "count primes"
   <> short 'c'
   <> long "count")