tags:

views:

79

answers:

2

Hi, I have just typed in the RandomState example from real world haskell. It looks like this:

import System.Random
import Control.Monad.State

type RandomState a = State StdGen a

getRandom :: Random a => RandomState a
getRandom =
  get >>= \gen ->
  let (val, gen') = random gen in
  put gen' >>
  return val

getTwoRandoms :: Random a => RandomState (a, a)
getTwoRandoms = liftM2 (,) getRandom getRandom

It works, but the result doesn't get displayed. I get the error message:

No instance for (Show (RandomState (Int, Int)))
  arising from a use of `print' at <interactive>:1:0-38
Possible fix:
  add an instance declaration for (Show (RandomState (Int, Int)))
In a stmt of a 'do' expression: print it

I am having some trouble adding an instance for Show RandomState. Can anyone show me how this is done?

Thanks.

+1  A: 

Since RandomState is a synonym for State and there isn't an instance of show defined for State, you won't be able to show it.

You would also not be able to derive show because State is just a wrapper for a function and Haskell has no way to define a show for functions that would be useful:

Prelude> show (+)

<interactive>:1:0:
    No instance for (Show (a -> a -> a))
      arising from a use of `show' at <interactive>:1:0-7
    Possible fix: add an instance declaration for (Show (a -> a -> a))
    In the expression: show (+)
    In the definition of `it': it = show (+)

EDIT: Forgot to add the other piece: GHCi is giving you that error because it uses show behind the scenes on the expressions you enter... REPL and all that.

jberryman
+2  A: 

For the sake of being explicit, as jberryman and the comments on the question imply: Something of type RandomState (a, a) is a function, not a value. To do anything with it, you want to run it with an initial state.

I'm guessing you want something like this:

> fmap (runState getTwoRandoms) getStdGen
((809219598,1361755735),767966517 1872071452)

This is essentially what the runTwoRandoms function a bit further in RWH is doing.

camccann
I am going to have to read that chapter again. I really thought I was starting to get it.
Kurt
@Kurt: Is it the "hidden" function that's tripping you up? It is kind of confusing that you can treat something of type `State s a` like a value of type `a` inside a `do` block, despite it actually being a function of type `s -> (a, s)`. Walking through a reimplementation of `State` seems to help some people get a better feel for how and why it works--I did that in [one of my previous answers](http://stackoverflow.com/questions/1956518/1957379#1957379) and I've seen a blog post or two go through it as well.
camccann
@Kurt: The State monad is weird. Think about it this way: all the monadic machinery (`>>=`, `return`, etc.) is *composing* a big function in the `State` wrapper. You then *do* stuff with that monad/function by applying `runState` which just take that function out of the `State` wrapper (like `fst` pulls the first element of a tuple, they just gave `runState` a clever name to confuse you)
jberryman