[Haskell-cafe] Text formatting question

Ryan Ingram ryani.spam at gmail.com
Thu Jun 4 13:32:01 EDT 2009


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 <evan at eklitzke.org> 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 <evan at eklitzke.org> :wq
> _______________________________________________
> Haskell-Cafe mailing list
> Haskell-Cafe at haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe
>


More information about the Haskell-Cafe mailing list