two easy questions

paul@theV.net paul@theV.net
Mon, 24 Feb 2003 15:26:53 +0800


On Fri, Feb 21, 2003 at 06:33:10PM +0100, Stefan Karrmann wrote:
> Mike T. Machenry (Wed, Feb 19, 2003 at 10:23:45PM -0500):
> > Question 1: Is there an easier, more elegant way to write this code?
> > 
> > output a b c d e = println "Hello, this is " ++ show a ++ " a really hard "
> >   "to write function that " ++ show b ++ " would be easier to write with "
> >   "a printf " ++ show c ++ show d ++ show e
> You can write a printf-like function in Haskell, s.t.
> output = <construct-printf.hs>
> 
> google it, since I do not remember the location of the paper.

I don't remember the paper's URL either, but here is a sample
implementation:

data End = End
data L fmt = L String fmt
data S fmt = S fmt
data I fmt = I fmt

class Format fmt x | fmt->x where
    format'   :: fmt -> String -> x

instance Format End String where
    format' (End) out = out

instance (Format fmt x) => Format (L fmt) x where
    format' (L s fmt) out = format' fmt (out++s)
 
instance (Format fmt x) => Format (S fmt) (String->x) where
    format' (S fmt) out = \s -> format' fmt (out++s)

instance (Format fmt x) => Format (I fmt) (Int->x) where
    format' (I fmt) out = \i -> format' fmt (out++ show i)

format :: (Format fmt x) => (End -> fmt) -> x
format f = format'  (f End) "" 

lit = L

str = S

int = I

main = putStrLn (format (int.lit " is ".str) 5 "five")

So you see the part (int.lit " is ".str) is to construct something
like "%d is %s" in printf. You may extend the idea to support other
types too.

Regards,
.paul.