Brian Hulley wrote:
Hi, I'm designing an API for a simple graphics window, and am trying to make the correct usage of the API functions explicit and visible to the type system by using different monads which ultimately just wrap the IO monad. For example, in a callback for rendering stuff to the screen, only operations in the RenderM monad are allowed, and when specifying vertex info for a primitive, only VertexM operations are allowed.
However I'm wondering if I can rely on all this monad stuff being optimized out at compile time. A sample monad is below:
newtype VertexM a = VertexM (IO a)
instance Monad VertexM where VertexM x >>= fry = VertexM $ do ax <- x let VertexM y = fry ax y
return x = VertexM $ return x
instance MonadIO VertexM where liftIO = VertexM
There should be no overhead for a newtype. The above can be shortened to one line: newtype VertexM a = VertexM (IO a) deriving (Functor,Monad,MonadIO) (Needs ghc -fglasgow-exts, I expect)
Also, in:
foreign import ccall duma_vertex3f :: Float -> Float -> Float -> IO ()
vertex3f :: Float -> Float -> Float -> VertexM () vertex3f x y z = liftIO $ duma_vertex3f x y z
is there a penalty involved in calling vertex3f (from another module) or will the worker/wrapper optimization ensure that machine code in the other module just calls duma_vertex3f directly since the liftIO operation is just an irrelevance at the machine code level?
I doubt there is a penalty.
So far I've just been using ghc --make and not bothering about what kind of code is generated. Is there a flag I can use to get ghc to output the stg code (or something higher level than just x86 machine code itself) so I can look at the output to see what optimizations are being done?
Thanks, Brian.
Yes, there are several ghc options: -ddump-<insert keyword> is documented in http://www.haskell.org/ghc/docs/latest/html/users_guide/options-debugging.ht... In particular -ddump-simpl has been helpful for some people, and you want -ddump-stg, perhaps.