There's a new version of this as v2 - Adding a duplicate entry randomly into a list in haskell using random monad
I wrote this trying to set up a Haskell testcase. The aim is to take a list and add a single duplicate from any place in the list to anywhere else in the list.
I'm trying to learn to use the Random Monad properly so the main aims should be clear, simple, idiomatic and pure code. However any recommendations for improvement are appreciated.
-- duplicate-to-list-randmonad.hs by Michael De La Rue 2014
-- licensed to StackEschange under cc by-sa 3.0
-- may also be used under AGPLv3
-- N.B. Trivial copying of code fragments does not normally require any license.
import Data.List
import Control.Monad.Random
main :: IO ()
main = do putStrLn $ "list comparison " ++ prettyList list
g <- getStdGen
let shuffled = evalRand (infiniteDuplicateLists list) g
putStrLn $ "lists after \n" ++ intercalate "\n" ( map prettyList (take 5 shuffled))
where
list = ["a","b","c"]
infiniteDuplicateLists genlist = do
firstelt <- addRandomDuplicate genlist
restoflist <- infiniteDuplicateLists genlist
return $ firstelt : restoflist
prettyList :: (Show a) => [a] -> String
prettyList list = " [ " ++ intercalate "," (map show list) ++ " ] "
addRandomDuplicate :: MonadRandom m => [a] -> m [a]
addRandomDuplicate genlist = do
frompos <- getRandomR (0 ,length genlist - 1)
topos <- getRandomR (0 ,length genlist)
let newlist = listEntryDuplicate (fromIntegral frompos) (fromIntegral topos) genlist
return newlist
listEntryDuplicate from to list =
start ++ [repeat] ++ end
where
repeat = list !! from
(start, end) = splitAt to list
(edited to move fixed code to a new question version for neatness)