Yesterday morning I decided to stop procrastinating and start learning me some Haskell.So far I've made this, which is a simple cli 'dice rolling' utility that can be used like:$ ./dice 3d20You rolled: 17The code looks like this:import Data.List.Splitimport Data.Charimport Control.Monadimport Control.Monad.Randomimport System.Environmenttype Dice = (Int, Int)diceCode :: String -> DicediceCode die = (parts!!0, parts!!1)  where    parts = [read x :: Int | x <- take 2 (splitOn D (map toUpper die))]rollDie :: (RandomGen g) => Int -> Rand g IntrollDie sides = getRandomR (1, sides)rollDice :: (RandomGen g) => Dice -> Rand g IntrollDice dice = liftM sum (sequence(replicate rolls (rollDie sides)))  where    rolls = fst dice    sides = snd dicemain = do  args <- getArgs  roll <- evalRandIO (rollDice (diceCode (args!!0)))  putStrLn (You rolled:  ++ show roll)I was able to get the diceCode 'parsing' function by myself without too much trouble.The rollDie function is almost straight from an example in the Control.Monad.Random docs, which helped a lot.I struggled for quite a while to find a recipe for summing the rolls in rollDice... it seemed to me I ought to use msum but I couldn't find a way to make it work. liftM sum seems to do exactly what I wanted though.I also found the use of tuples quite cumbersome. In Python I could just do:rolls, sides = dicebut I seem to have to use the horribly-named fst and snd functions to access the members in Haskell (?)I guess the next part of my adventure is to try and incorporate this into a larger program, eg a simple game.  It seems like the monadically-wrapped random int values are going to force the rest of the code to be 'monad-aware' (i.e. lots of use of liftM) and I wonder if there is a way to avoid this?
My first Haskell: dice rolling
beginner;haskell;dice