4

In the following code, how can I replace put 1 with some code that insert nondeterministically 1 or 2 in the state?

import Control.Monad.List
import Control.Monad.Trans.State

test :: StateT Int [] Int
test = do
  put 1
  v <- get
  return v
Bob
  • 1,713
  • 10
  • 23
  • 4
    @CarstenKönig It seems clear to me, at least, that he is using "non-deterministically" in [a quite standard way](https://www.google.com/search?q=nondeterminism+monad). – Daniel Wagner Aug 02 '14 at 08:12

2 Answers2

9

Your monad stack signature is already the correct one.

Lift a computation from the [] monad and bind to its value. This will fork the computation:

test :: StateT Int [] Int
test = do
  s <- lift [1,2,3]
  put s
  v <- get
  return v

Testing to see it works:

*Main> runStateT test 10
[(1,1),(2,2),(3,3)]

Not only there are many results, but the state gets included in the nondeterminism as well.

If test had had type ListT (State Int) Int, only the results would have been nondetermistic, the state would have been shared among all the branches in the computation:

test :: ListT (State Int) Int
test = do
  s <- ListT $ return [1,2,3]
  put s
  v <- get
  return v

The result:

*Main> runState (runListT test) 10
([1,2,3],3)
danidiaz
  • 26,936
  • 4
  • 45
  • 95
2

maybe you want something like this instead:

import Control.Monad.List
import Control.Monad.Trans.State
import System.Random (randomIO)

test :: StateT Int IO Int
test = do
  put1 <- liftIO $ randomIO
  put (if put1 then 1 else 2)
  v <- get
  return v

This will use the global generator to set 1 or 2 at random

Random Dev
  • 51,810
  • 9
  • 92
  • 119
  • 1
    Although my question was not about probabilistic computation, this answer is interesting. – Bob Aug 02 '14 at 10:27
  • I was not thinking about this - I guess I just missunderstood your real question sorry for that - but if you find it interesting I will let this in here – Random Dev Aug 02 '14 at 10:28
  • Might I recommend monad random instead? Or RandT? – PyRulez Aug 02 '14 at 19:58
  • Sure - `ranndomIO` is just the easiest one (I now of) that's why I took this - it's not what was asked for but maybe you can add one answer if the OP is interested – Random Dev Aug 02 '14 at 21:31