I am new to monads in Haskell.
I was trying to write a scatter graph with Haskell-chart that would plot 20 points with strong (but not perfect) positive correlation. Example of what I was trying to do. Specifically, I want a list of random doubles in the range 0.8 to 1.0 to multiply with my y-vals to reduce the correlation coefficient a bit. My original implementation was this:
import Graphics.Rendering.Chart.Easy
import Graphics.Rendering.Chart.Backend.Cairo
import System.Random
import Lib (xvals)
main = toFile def "chart.png" $ do
layout_title .= "My chart"
layout_x_axis . laxis_override .= axisGridHide
plot (points "My points" [(x,y) | (x,y) <- let vs = xvals 20 0.0 10.0 in zip vs $ zipWith (*) vs noise])
where noise = filter (>0.8) $ randoms $ mkStdGen 1
which worked, but had the flaw that since the seed for mkStdGen
was static, I would get the same points regardless of how many times I rebuilt and executed the code. So I tried this to generate a dynamic seed:
import Graphics.Rendering.Chart.Easy
import Graphics.Rendering.Chart.Backend.Cairo
import System.Random
import Lib (xvals)
main = toFile def "chart.png" $ do
layout_title .= "My chart"
layout_x_axis . laxis_override .= axisGridHide
seed <- (randomIO :: IO Int)
plot (points "My points" [(x,y) | (x,y) <- let vs = xvals 20 0.0 10.0 in zip vs $ zipWith (*) vs noise)])
where noise = filter (>0.8) $ randoms $ mkStdGen seed
The error message I get for the above is:
• Couldn't match type ‘IO’
with ‘transformers-0.5.6.2:Control.Monad.Trans.State.Lazy.StateT
(Layout Double Double)
(transformers-0.5.6.2:Control.Monad.Trans.State.Lazy.State CState)’
Expected type: transformers-0.5.6.2:Control.Monad.Trans.State.Lazy.StateT
(Layout Double Double)
(transformers-0.5.6.2:Control.Monad.Trans.State.Lazy.State CState)
Int
Actual type: IO Int
I think it is due to toFile def "chart.png"
but I don't know why, or how to get this working with randomIO
. As far as I know, seed :: Int
so this should work. Any help would be appreciated.