[Haskell-cafe] A Typing Dilemma

Scott Turner p.turner at computer.org
Fri Oct 8 11:36:33 EDT 2004


On 2004 October 08 Friday 09:57, John Goerzen wrote:
> defaultHandler :: LogHandler b => IO (a -> IORef b)
> defaultHandler = do
>                  h <- (streamHandler stdout WARNING)
>                  r <- newIORef h
>                  return (\x -> r)
>
> The idea is to create a new IORef to something in the LogHandler class
> and return a function that returns it.  The thing returned by that call
> to streamHandler is in the LogHandler class.  Specifically, its
> declaration looks like this:
>
> instance LogHandler (GenericHandler a) where

defaultHandler returns its result for _some_ LogHandler type, while the type 
declaration
> defaultHandler :: LogHandler b => IO (a -> IORef b)
has an implicit universal interpretation of b.  To satisfy this type 
declaration, defaultHandler would have to be able to return a handler for 
_any_ LogHandler type, depending on the context in which defaultHandler is 
called.

The Haskell type for defaultHandler uses an existential type, and would look 
like this:

data SomeLogHandler = forall a . (LogHandler a) => SomeLogHandler a
defaultHandler :: IO (a -> IORef SomeLogHandler)
defaultHandler = do
                 h <- (streamHandler stdout WARNING)
                 r <- newIORef (SomeLogHandler h)
                 return (\x -> r)

Then you would use it as
                 f <- defaultHandler
                SomeLogHandler h <- readIORef (r 0)
                ... use the LogHandler h ...

By the way, when you say "return a function that returns it", I suspect you 
are thinking of how this would work in C or Java, where to accomplish 
anything you need to call a function or invoke a method.  If the function 
parameter of type 'a' serves no useful purpose, then the above can be 
simplified to 

data SomeLogHandler = forall a . (LogHandler a) => SomeLogHandler a
defaultHandler :: IO (IORef SomeLogHandler)
defaultHandler = do
                 h <- (streamHandler stdout WARNING)
                 r <- newIORef (SomeLogHandler h)
                 return r

Then you would use it as
                 f <- defaultHandler
                SomeLogHandler h <- readIORef r
                ... use the LogHandler h ...


More information about the Haskell-Cafe mailing list