RE: Record of STRefs better than STRef to a Record?

If I use an STRef to a record, will a new record be created each time I want to update a single field? Or can I expect GHC to optimize it and have the field of the record updated in place?
You'll get a new record for each update. This might not be so bad though, depending on the number of fields in your record.
Right now I'm using a record of STRefs, like: data E s = E{ refi :: STRef s Int, refc :: STRef s Char }
but it can get a little messy, since thread s propagates to every datatype that uses the record type in it's definition.
Here's another trick if you use this route: data E s = E{ refi :: !STRef s Int, refc :: !STRef s Char } and compile with -funbox-strict-fields. This will eliminate the boxing of the STRefs. Cheers, Simon

If I use an STRef to a record, will a new record be created each time I want to update a single field? Or can I expect GHC to optimize it and have the field of the record updated in place?
You'll get a new record for each update. This might not be so bad though, depending on the number of fields in your record. One of them has 4, the other 3, but they might grow bigger...
Here's another trick if you use this route: <added some parenthesis> data E s = E{ refi :: !(STRef s Int), refc :: !(STRef s Char) }
and compile with -funbox-strict-fields. This will eliminate the boxing of the STRefs.
Nice, thanks :) One more question. I'm passing that 'record' around as an implicit value. The record as STRefs that I use to collect info, but it also has some pure fields with 'read-only' info. Something like, data E s = E{ refi :: STRef s Int, refc :: STRef s Char, max :: Int } In some functions I might need only some pure fields, and none of the STRefs, but since I pass something of type 'E s' around, everything ends up beeing monadic. Is using two records (on with STRefs and one with pure fields) the only/best way to avoid this? I would like to use two records, doesn't seem natural, but I also don't like to end up using monadic functions when they are, in fact, pure... Thanks, J.A.

On Thursday 14 November 2002 01:29 am, Jorge Adriano wrote:
In some functions I might need only some pure fields, and none of the STRefs, but since I pass something of type 'E s' around, everything ends up beeing monadic. Is using two records (on with STRefs and one with pure fields) the only/best way to avoid this? I would like to use two records, doesn't seem natural, but I also don't like to end up using monadic functions when they are, in fact, pure...
Good question. In all Haskell codes I wrote, I ended up writing a lot of
monadic functions which seemed to be unavoidable. Then you look at the code
as it feels too much like an imperative code and start wondering why you are
using a functional language :)
Happy new year to all Haskellers by the way.
Cheers,
--
Eray Ozkural

hello,
Well, actually you must be right since the pure field defines a pure (projection) function... Hmmm, ok, can someone explain this to me,
data E s = E{ refi :: STRef s Int, refc :: STRef s Char, m :: Int }
-- this is fine, obviously... pure :: E s -> Int pure e = m e
-- but this is not... pure2 :: (?e :: E s) => Int pure2 = m (?e)
Why exactly isn't this allowed? What is the workaround? Error msg: ------------------------------------------------------------------------ Ambiguous constraint `?e :: E s' At least one of the forall'd type variables mentioned by the constraint must be reachable from the type after the '=>' In the type: forall s. (?e :: E s) => Int While checking the type signature for `pure2' Failed, modules loaded: none. --------------------------------------------------------------------------
this seems like a bug in GHC. Hugs is happy with it. The "s" in the pure2 signature is not ambiguous because it is determined when you give the value of the implicit parameter. in fact the way i think about implicit parameters is simply as a nice notation for computations in the environment monad, so in my mind the above two definitions are pretty much the same. bye iavor -- ================================================== | Iavor S. Diatchki, Ph.D. student | | Department of Computer Science and Engineering | | School of OGI at OHSU | | http://www.cse.ogi.edu/~diatchki | ==================================================

On Thursday 14 November 2002 18:47, Iavor S. Diatchki wrote:
hello,
Well, actually you must be right since the pure field defines a pure (projection) function... Hmmm, ok, can someone explain this to me,
data E s = E{ refi :: STRef s Int, refc :: STRef s Char, m :: Int }
-- this is fine, obviously... pure :: E s -> Int pure e = m e
-- but this is not... pure2 :: (?e :: E s) => Int pure2 = m (?e)
Why exactly isn't this allowed? What is the workaround? Error msg: ------------------------------------------------------------------------ Ambiguous constraint `?e :: E s' At least one of the forall'd type variables mentioned by the constraint must be reachable from the type after the '=>' In the type: forall s. (?e :: E s) => Int While checking the type signature for `pure2' Failed, modules loaded: none. ------------------------------------------------------------------------- -
this seems like a bug in GHC. Hugs is happy with it. The "s" in the pure2 signature is not ambiguous because it is determined when you give the value of the implicit parameter. in fact the way i think about implicit parameters is simply as a nice notation for computations in the environment monad, so in my mind the above two definitions are pretty much the same.
Thanks Iavor! GHC people, can you confirm this, Is it a bug? I'm using Ghc 5.0.4 SuSE rpms. Is there a workaround? Thanks, J.A.
participants (4)
-
Eray Ozkural
-
Iavor S. Diatchki
-
Jorge Adriano
-
Simon Marlow