Patrick Logan <[EMAIL PROTECTED]> writes:
> In "Rolling Your Own Mutable ADT: A Connection Between Linear Types
> and Monads", p. 1, Chen and Hudak write:
>
> There are few formal connections between monads and
> single-threaded state... For any state-transformer monad... there
> is a trivial operation... that will instantly destroy any hope for
> single-threadedness: getState s = (s, s)
>
> In day-to-day Haskell 1.3 programming what is the solution to this
> problem? If a program is using a C interface to create a mutable
> state, say an external database, what is the simplest way of
> encapsulating the state so that this "trivial operation" cannot be
> defined except by the original author?
1) Visually inspect the implementation of your monad.
You might apply Chen and Hudak's technique or you might just rely on
your own intuition - simple cases aren't too hard.
2) Take a little time to decide what you should export and what you shouldn't.
Suppose you write a little state-transformer monad:
newtype S s a = MkS (s -> (a,s))
unMkS :: S s a -> (s -> (a,s))
unMkS (MkS x) = x
instance Monad S where
m >>= k = MkS (\ s1 -> case unMkS m s1 of { (a,s2) -> unMkS (k a) s2 })
return a = MkS (\ s -> (a,s))
getS :: S s s
getS = MkS (\ s -> (s,s))
setS :: s -> S s ()
setS s = MkS (\ _ -> ((),s))
Obviously you want to export S, >>=, return, getS and setS.
You also want to prevent people from creating random state transformer
functions - so we'd better hide the MkS.
I don't think there's any harm in exporting unMkS, but I don't see
any point in doing so and it's best to keep your data types abstract.
Here's what your export list should look like:
module StateTransformer
( S -- export the type "S" but not its constructors
, getS -- export the state modifiers
, setS
-- no need to export >>= and return - they're automatically exported
) where
Hope this helps!
--
Alastair Reid Yale Haskell Project Hacker
[EMAIL PROTECTED] http://WWW.CS.Yale.EDU/homes/reid-alastair/