Here is an example of how you can use getArgs:
module Main where
import System.Environment (getArgs)
main :: IO ()
main = do
args <- getArgs
if length args == 5
then putStrLn "You gave me 5 args!"
else putStrLn "You didn't give me 5 args!"
Edit: It was length args, not args, thanks.
Edit: But note that getArgs on ./my_program --a 30 --b 20 will, unlike in C, not mention ./my_program as part of the arguments. If you want the program name it's getProgName. Otherwise, the right number is probably 4. For the sake of working with the IO monad, you could extend the program to print out the name of the executable:
import System.Environment (getArgs, ...)
main = IO ()
main = do
args <- getArgs
name <- ...
putStrLn ("Program: " <> show name)
if length args == 4
...
But what you appear to be going for is argument parsing, not just counting.
You could use optparse-generic to auto-generate an argument parser based on a datatype.
There is an example in the documentation for Options.Generic that I turned into a template project here, with the important parts mentioned below for posterity:
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TypeOperators #-}
module Main where
import Control.Monad.IO.Class (MonadIO)
import Options.Generic
data Config w = Config
{ bleeps :: w ::: Int <?> "Number of bleeps"
, bloops :: w ::: Int <?> "Number of bloops"
} deriving (Generic)
instance ParseRecord (Config Wrapped)
deriving instance Show (Config Unwrapped)
main :: IO ()
main = do
config <- getConfig
putStrLn $
"I got " <> show (bleeps config) <> " bleeps, and "
<> show (bloops config) <> " bloops."
getConfig :: IO (Config Unwrapped)
getConfig = unwrapRecord "Hello"
If you replace bleeps and bloops with a and b, you can run the program with e.g.
$ stack run -- --a 30 --b 20