2008/5/8 Madoc <[EMAIL PROTECTED]>: > Hello, > > I am just learning Haskell. Now, I encountered something that I cannot > solve by myself. Your advice will be greatly appreciated. > > Given a list of numbers, I want to modify each of those numbers by adding a > random offset. However, each such modified number shall stay within certain > bounds, given by the integers minValue and maxValue. After that, I want to > continue computation with the resulting list of type [Int]. But for > demonstration, I made a program that just prints out the list: > > import IO; import Random > > minValue = 0::Int > maxValue = 1000::Int > > normalize a | a < minValue = minValue > | a > maxValue = maxValue > | otherwise = a > > modify a = do > offset <- randomRIO(-100::Int, 100) > return(normalize(a + offset)) > > main = putStrLn $ show $ map (modify) [0, 200, 400, 600, 800, 1000] > > This program will not compile. GHC complains: > > test.hs:14:18: > No instance for (Show (IO Int)) > arising from a use of `show' at test.hs:14:18-21 > Possible fix: add an instance declaration for (Show (IO Int)) > In the first argument of `($)', namely `show' > In the second argument of `($)', namely > `show $ map (modify) [0, 200, 400, 600, ....]' > In the expression: > putStrLn $ show $ map (modify) [0, 200, 400, 600, ....] > > I understand that the result of the modify function is not an Int, as I > would like to have it, but instead IO Int, and that cannot be applied to > show. (I also did not quite understand why I need those brackets around > the return value of the modify value. It won't compile if I leave them > out, but I can accept that for now.) > > I also figured out how to generate a modified list of type [IO Int] and of > type IO [Int]. However, I could not find out how to completely get rid of > the IO monad and just get a mofied list of type [Int], which is what I > really want. > > Please, do You have any advice for me? I tried for some hours, and now I am > really angry at that IO monad that sticks to my pretty integers like glue! > > Also, any comment on the programming style and how I could achive my goals > easier would be appreciated. (I left out comments and function types for the > sake of brevity.) >
You should use newStdGen to produce a random generator, then randomRs to produce a list of random numbers (without using IO!). But if you really want this version with IO interspersed through the algorithm to work, then something like this should do it (uncompiled): main = do xs <- mapM (modify) [0, 200, 400, 600, 800, 1000] putStrLn $ show $ xs The only way to "get rid of the IO monad", is to use "<-" to bind it to a value from within the IO monad. -- Sebastian Sylvan +44(0)7857-300802 UIN: 44640862
_______________________________________________ Haskell-Cafe mailing list [email protected] http://www.haskell.org/mailman/listinfo/haskell-cafe
