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")