Mixing internal functions and datatypes with externally available ones

Hello. I'm writing a library - some kind a wrapper around SDL library, an engine. For example, I have a module Graphics.UI.SDL.XEngine.State and functions modifyState and setColor in it. These functions are using "global" variable of type IO (IORef XState). I want to use the first function in Graphics.UI.SDL.XEngine.General and Graphics.UI.SDL.XEngine.Drawing modules and I don't want this function to be accessible from a program which uses my library, but I need to make the function setColor visible from everywhere. Is there a simple way to do such thing? Or maybe I should restructure my library?

On Sun, Dec 27, 2009 at 5:51 AM, DPX-Infinity
Hello. I'm writing a library - some kind a wrapper around SDL library, an engine. For example, I have a module Graphics.UI.SDL.XEngine.State and functions modifyState and setColor in it. These functions are using "global" variable of type IO (IORef XState). I want to use the first function in Graphics.UI.SDL.XEngine.General and Graphics.UI.SDL.XEngine.Drawing modules and I don't want this function to be accessible from a program which uses my library, but I need to make the function setColor visible from everywhere. Is there a simple way to do such thing? Or maybe I should restructure my library?
Well you should definitely restructure your library. Global variables in other languages are looked down upon (and they invented the "singleton" pattern to justify their sin), but in Haskell they are simply not acceptable. Haskell functions have the beautiful property that they work just as well in my program as in yours -- they make no reference to the context in which they exist. A global variable breaks this property. Anyway, it sounds like you may not have one anyway. A value of type IO (IORef ...) is not a variable, but an action returning a mutable cell. So if you have something like: foo :: IO (IORef Int) foo = newIORef 10 Each time foo is bound it will return a fresh variable with initial value 10. And this is perfectly acceptable Haskell (because it is not global state), but probably not what you wanted. Anyway, to get the accessibility you are going for, you should not expose General in your library interface (you can specify which modules are exposed in your cabal file). Use General within your library, and write another module that is exposed and that re-exports what you want users to be able to see. Does that make sense? Luke
participants (2)
-
DPX-Infinity
-
Luke Palmer