Suppose I have the following Haskell code:
data Option
= Help
| Opt1 Int Double String
-- more options would be here in a real case
handleOption :: Option -> IO ()
handleOption option = case option of
Help -> handleHelp
Opt1 n f s -> handleOpt1 n f s
handleHelp :: IO ()
handleHelp = print "help"
handleOpt1 :: Int -> Double -> String -> IO ()
handleOpt1 n f s = print (n, f, s)
In the above code, it seems to me a waste to deconstruct the object ahead of time in the sense that I could keep the data bundled neatly together. Now I have to pass each part of Opt1 individually or create a single separate data type to haul them along. Is it possible to pass in the entire Opt1 to handleOpt1 while not allowing a general Option instance being passed in, such as making handleOpt1 Help a compile error?
Example pseudo code below:
data Option
= Help
| Opt1 Int Double String
handleOption :: Option -> IO ()
handleOption option = case option of
Help -> handleHelp
opt1 @ Opt1{} -> handleOpt1 opt1
handleHelp :: IO ()
handleHelp = print "help"
handleOpt1 :: Option:Opt1 -> IO ()
handleOpt1 (Opt1 n f s) = print (n, f, s)
handleOpt1was constructed with the right constructor (in general; it could in principle check that values that are explicitly passed in the source code are, but since usually passed values are computed during run time, nobody wrote the code to check the exceptional case).