Sigbjorn Finne wrote:
If you let the Simplifier have a crack at your code (i.e., compile
with -O or better), the same code should be generated for the two
defns of 'foo'. Try compiling with -ddump-simpl to verify.

Thanks. I tried that and you're right. It also works well with an even more complicated example:

   data R = R{_xRef :: !(Ref.T Int), _y :: Int}

   foo :: Bool -> R -> IO ()
   foo b r = do
       if b
           then Ref.write (_xRef r) ((_y r) * (_y r))
           else return ()
       x <- Ref.read (_xRef r)
       print x

Even though there are 4 applications of field label functions and _y is not even a strict field, GHC -O2 manages to get both fields with a single case statement:

   Main.foo :: GHC.Base.Bool -> Main.R -> GHC.IOBase.IO ()
   [GlobalId]
   [Arity 3
       Worker Main.$wfoo
       Str: DmdType SU(U(L)L)L]
   Main.foo = __inline_me (\ (w_s2sp :: GHC.Base.Bool)
           (w1_s2sq :: Main.R)
           (w2_s2sy :: GHC.Prim.State# GHC.Prim.RealWorld) ->
           case (# GHC.Prim.State# GHC.Prim.RealWorld, () #) w1_s2sq
           of w3_X2sB { Main.R ww_s2ss ww1_s2sw ->

               -- well done GHC!!!! :-)

           case (# GHC.Prim.State# GHC.Prim.RealWorld, () #) ww_s2ss
           of ww2_X2sI { GHC.STRef.STRef ww3_s2su ->
           Main.$wfoo w_s2sp ww3_s2su ww1_s2sw w2_s2sy
           }
           })

This is great because some of my records have about 20 fields so the pattern matching was getting really cumbersome in the source.

BTW I made a module to make the IORef functions work with any MonadIO and also give them better names (to use by qualified import) which I enclose below if anyone is interested - I don't know where to put stuff like this:

----------------------------------------------------------------
-- |
-- Module: Prime.IORef
-- Author: Brian Hulley
-- License: Public Domain
--
-- Lifts (most of) Data.IORef to any MonadIO
-- This module should be used qualified so we can avoid
-- writing "IORef" everywhere
----------------------------------------------------------------
module Prime.IORef
   ( T
   , new
   , read
   , write
   , modify
   , weak
   ) where

   import Prelude hiding(read)
   import qualified Data.IORef as D
   import Control.Monad.Trans
   import System.Mem.Weak

   type T = D.IORef

   new :: MonadIO m => a -> m (T a)
   new x = liftIO $ D.newIORef x

   read :: MonadIO m => T a -> m a
   read x = liftIO $ D.readIORef x

   write :: MonadIO m => T a -> a -> m ()
   write x v = liftIO $ D.writeIORef x v

   modify :: MonadIO m => T a -> (a -> a) -> m ()
   modify x f = liftIO $ D.modifyIORef x f

   weak :: MonadIO m => T a -> m (Weak (T a))
   weak r = liftIO $ D.mkWeakIORef r (return ())

Regards, Brian.

--
Logic empowers us and Love gives us purpose.
Yet still phantoms restless for eras long past,
congealed in the present in unthought forms,
strive mightily unseen to destroy us.

http://www.metamilk.com
_______________________________________________
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users

Reply via email to