Home > front end >  ST Monad usage outside of `do` in Haskell?
ST Monad usage outside of `do` in Haskell?

Time:02-03

I see lots of examples of ST monad in the context of do notation; however since that's not suitable to my purpose, I try to use ST monad for instance newSTRef and modifySTRef outside of do thread.

The type is automatically added by HLS of VSCode.

ref :: ST s (STRef s Integer)
ref = newSTRef (1)

x :: ST s ()
x = modifySTRef ref 2

error: ref in the last line

Couldn't match expected type ‘STRef s a0’
            with actual type ‘ST s0 (STRef s0 Integer)’

Well, sure I can see the error saying the type doesn't match, but I don't know how to fix it.

What is the proper usage of ST Monad outside of do?

EDIT:

My purpose without do is

  1. like the one mentioned, do is merely a syntax sugar and often I'd like to avoid it in order to write a code in more straightforward functional way.

  2. The purpose to obtain the mutable object is to develop FRP, and the sequential definition and updates of ref in the single do thread is not useful for the purpose.

CodePudding user response:

The problem here is that modifySTRef takes an STRef s a, not a ST s (STRef s a). ST was designed to utilize monad properties to secure mutable operations from being abused, so all modifications can happen only in an ST context. Therefore, you need to use the powers of the context to extract the pure STRef reference.

Normally you would do it like this:

x :: ST s ()
x = do
  refv <- ref
  modifySTRef refv 2

But since you would like to avoid this sugar, you can do right what it desugars to:

x :: ST s ()
x = refv >>= \refv -> modifySTRef refv 2

You can read more about the do notation and how it is resolved here

  •  Tags:  
  • Related