[Haskell-cafe] Refactoring from State monad to ST monad, for STUArray

Daniel Fischer daniel.is.fischer at web.de
Sat Feb 2 17:51:18 EST 2008


Am Samstag, 2. Februar 2008 23:17 schrieb Denis Bueno:
> Thanks for all the responses.  I have never used monad transformers
> before, but StateT is welcome and really cool.  I didn't even think to
> look them up.
>
> I have a follow up question.  I eventually get to a point where I have
> a value of type (ST s (Maybe (STUArray s Int Int))), and I need
> somehow to get rid of the Maybe, so I can call runSTUArray on it.  The
>
> function containing this value returns a pure type:
> > data Solution = Sat (UArray Int Int) | Unsat deriving (Eq)
>
> I've included the function body below, along with a few comments that
> hopefully make my problem clear enough.  Let me know if there's any
>
> more detail needed:
> > solve :: StdGen -> Cnf -> Solution
> > solve rnd cnf =
> >    -- To solve, we simply take baby steps toward the solution using
> > solveStep, -- starting with the empty assignment.
> >    Sat . runSTUArray $
> >    do solution <- -- this block, as you can see,
> >                   -- is the (ST s (STUArray s Int Int)) value
> >          evalStateT (stepToSolution $ do
> >                        initialAssignment <- lift (newArray (1, numVars
> > cnf) 0) solveStep initialAssignment)
> >          SC{cnf=cnf, dm=Map.empty, dl=[], bad=Set.empty, rnd=rnd}
> >       case solution of -- `solution' is the (Maybe (STUArray s Int Int))
> > value Nothing -> error "unsat"
> >         Just m -> return m
>
> Using `error' in the Nothing case is exactly what I'd like to avoid.
> How should I improve this?

Would

solve rnd cnf =
    case evalStateT ... of
	Nothing -> Unsat
	Just st -> Sat $ runSTUArray st

work? Might need some explicit 'forall s.' or not typecheck at all, didn't 
test.



More information about the Haskell-Cafe mailing list