You can use CPS printf, which has the advantage of being completely type-safe:
> lit :: String -> (String -> r) -> r > lit s k = k s > str :: (String -> r) -> (String -> r) > str k s = k s > val :: Show a => (String -> r) -> a -> r > val k a = k (show a) > (^) :: ((String -> r) -> s) -> ((String -> s) -> t) -> ((String -> r) -> t) > (a ^ b) k = b $ \s -> a $ \t -> k (s ++ t) > cprintf :: ((String -> String) -> s) -> s > cprintf k = k id ghci> :t cprintf (val ^ lit "a" ^ val) cprintf (val ^ lit "a" ^ val) :: (Show a, Show a1) => a1 -> a -> [Char] ghci> putStrLn $ cprintf (val ^ lit "a" ^ val) 5 () 5a() This can be improved further by using difference lists instead of Strings as the carrier type, to avoid bad behavior in ++, but it's good enough for most uses. It's definitely more wordy than the raw printf, but you can use Template Haskell to build real printf out of it: ghci> putStrLn $ $(sprintf "%va%v") 5 () 5a() Doing so is kind of fun, so I'll leave it as an exercise :) -- ryan On Thu, Jun 4, 2009 at 12:41 AM, Evan Klitzke <[email protected]> wrote: > I'm writing code with hslogger, and I'm finding myself frequently > writing things like this: > > infoM $ printf "%s saw %s with %s" (show x) (show y) (show z) > > On #haskell I asked about why you can't have use %s with any instance > of (Show a), and augustss, the Text.Printf maintainer, pointed out > that it's not possible in Haskell 98 because of overlapping instances. > So I'm trying to figure out the best way to work around this in my > code. Some of the logging statements can get kind of long, so the > ability to elide the calls to `show` would be nice. So what's the best > way to do this? > > I was thinking of making my own variant of printf that only accepted > the %s formatter and took (Show a)'s as arguments, but there might be > a simpler way? Another thing is the code is already fairly GHC > specific at this point, so if there are GHC extensions that might be > useful here that I don't know about, I'm interested in hearing about > them. > > Thanks. > > -- > Evan Klitzke <[email protected]> :wq > _______________________________________________ > Haskell-Cafe mailing list > [email protected] > http://www.haskell.org/mailman/listinfo/haskell-cafe > _______________________________________________ Haskell-Cafe mailing list [email protected] http://www.haskell.org/mailman/listinfo/haskell-cafe
