3
I studied the topic of Monad and decided to make a program to test my knowledge.
import           Control.Monad.IO.Class     (liftIO)
import qualified Control.Monad.State        as ST
import           Control.Monad.Trans.State  (StateT (..), evalStateT, get, put)
import qualified Control.Monad.Trans.Writer as WT
import           Data.List                  (sort)
import           Prelude                    hiding (max)
import           System.Random
randomSt :: (RandomGen g, Random a, Num a) => a -> ST.State g a
randomSt max = ST.state $ randomR (1, max)
lottery :: Integer -> Integer-> StateT [Integer] IO [Integer]
lottery 0 _ = get >>= return
lottery n max = do
  xs <- get
  x <- liftIO $ randomRIO (1, max)
  if x `elem` xs
     then lottery n max
     else do put (x:xs)
             lottery (n - 1) max
lotteryWt :: Integer -> Integer -> WT.WriterT [String] (StateT [Integer] (ST.State StdGen)) [Integer]
lotteryWt 0 _ = ST.lift get >>= return
lotteryWt n max = do
  xs <- ST.lift get
  x <- ST.lift . ST.lift $ randomSt max
  g <- ST.lift . ST.lift $ get
  WT.tell [show x ++ " " ++ show n ++ ", state from StateT " ++ show xs  ++ ", state from State " ++ show g]
  if x `elem` xs
     then lotteryWt n max
     else do ST.lift $ put (x:xs)
             lotteryWt (n - 1) max
main :: IO ()
main = do x <- evalStateT (lottery 6 60) []
          g <- newStdGen
          let y = ST.evalState (evalStateT (WT.runWriterT (lotteryWt 6 60)) []) g
          putStrLn $ show $ sort x
          putStrLn $ show $ sort (fst y)
          mapM_ putStrLn (snd y)
I have two stacks of Monad’s one StateT [Integer] IO [Integer] and the other WriterT .... For each Ottery function, I extract the values of each Monad.
I wanted to understand if this is the right way to use several Monad. It is a good practice this type of use?
I did some research on the subject Haskell - Avoiding lift with Monad Transformers and If you’re using lift, you’re Doing it wrongly (probably). But I didn’t find an answer, as soon as I find something, I’ll post.
– lemoce