oleg [1]: > We demonstrate typed sprintf and typed sscanf sharing the same > formatting specification.
[1]http://www.haskell.org/pipermail/haskell/2008-August/020605.html Reading Oleg's post, I noticed that it is quite straightforward to generalise printing to arbitrary output types. > class Monoid p => Printf p where > printChar :: Char -> p > --etc > > intp :: Printf p => F a b -> (p -> a) -> b > intp FChr k = \c -> k (printChar c) > intp (a :^ b) k = intp a (\sa -> intp b (\sb -> k (mappend sa sb))) > --etc > > printf :: Printf p => F p b -> b > printf fmt = intp fmt id The Printf instances for String, ShowS, ByteStrings, and IO () are all trivial. Printing directly to a file (without building an intermediate string) is slightly more interesting: > instance Monad m => Monoid (ReaderT r m ()) where > mempty = return () > mappend = (>>) > > instance Printf (ReaderT Handle IO ()) where > printChar c = ask >>= \h -> liftIO (hPutChar h c) > --etc > > (<<) :: Handle -> ReaderT Handle IO () -> IO () > (<<) = flip runReaderT > > test_fprintf h = h << printf (lit "Hello " ^ lit "World" ^ chr) '!' Unfortunately, I don't seem to be able to make the expected fprintf function, because printf's format-dependent parameter list makes it impossible to find a place to pass the handle. Hence the C++-like (<<) ugliness. _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe