Hi Phil,
Hi,
I'm trying to think around a problem which is causing me some difficulty in Haskell.
I'm representing a stateful computation using a State Transform - which works fine. Problem is in order to add flexibility to my program I want to performs the same operation using different techniques - most of which require no state.
My program at the moment is a stack of state monads/transforms. I have a random number generator as a state monad (seed=state), feeding a Box Muller (normal) generator implemented as a state transform (state is 'maybe' normal, so it only spits out 1 normal at a time), which in turn feeds another state machine.
This all works fine, but I want to add flexibility so that I can chop and change the Box Muller algorithm with any number of other normal generators. Problem is most of them do not need to carry around state at all.
This leaves me with a messy solution of implementing lots of state monads that don't actually have a state, if I want to maintain the current paradigm.
This strikes me as really messy - so I'm hoping someone can point me in the direction of a more sensible approach?
Currently I have my Box Muller implemented as below - this works:
class NormalClass myType where
generateNormal :: myType Double
type BoxMullerStateT = StateT (Maybe Double)
type BoxMullerRandomStateStack = BoxMullerStateT MyRngState
instance NormalClass BoxMullerRandomStateStack where
generateNormal = StateT $ \s -> case s of
Just d -> return (d,Nothing)
Nothing -> do qrnBaseList <- nextRand
let (norm1,norm2) = boxMuller (head qrnBaseList) (head $ tail qrnBaseList)
return (norm1,Just norm2)
But say I have another instance of my NormalClass that doesn't need to be stateful, that is generateNormal() is a pure function. How can I represent this without breaking my whole stack?
I've pretty much backed myself into a corner here as my main() code expects to evalStateT on my NormalClass:
main = do let sumOfPayOffs = evalState normalState (1,[3,5]) -- (ranq1Init 981110)
where
mcState = execStateT (do replicateM_ iterations mc) 0
normalState = evalStateT mcState Nothing
If it wasn't for this I was thinking about implementing the IdentityT transformer to provide a more elegant pass-through.
I've never tried designing my own Monad from scratch but this crossed my mind as another possibillity - i.e. a Monad that either has a state of maybe double, or has no state at all?