On Wed, Jul 20, 2005 at 07:00:22PM +0200, Lemmih wrote:
> On 7/20/05, Andy Gimblett <[EMAIL PROTECTED]> wrote:
> >
> > Is there a facility like this in Haskell? Or something else I should
> > be using, other than lots of ++ ?
>
> There's Text.Printf:
>
> Prelude Text.Printf> printf "(%s [] %s)" "hello" "world" :: String
> "(hello [] world)"
If you only use GHC, you can also implement (or borrow) a type-safe
printf using Template Haskell. I think there's some implementation
made by Ian Lynagh.
Recently I needed to build strings containing shell commands and I
also didn't like the ++ approach. I didn't like the printf approach,
but rather wanted something more like shell's or Perl's string
interpolation, so I could write something like "($p [] $q)" and have
$p and $q expanded to values of p and q.
I created a small TH library for this (attached). It uses such syntax:
$(interp "(%{p} [] %{q})"). I used % because I knew I would often have
to use literal $'s.
Unfortunately it has some problems. First, TH sometimes doesn't like
when I use a global variable in %{ }. I had to work around it by
defining additional local helper variables.
Second, it would be nice to be able to put arbitrary Haskell expressions
inside %{ } - but I couldn't find a Haskell syntax parser producing TH
ASTs. There must be some - I guess Template Haskell uses one internally.
Best regards
Tomasz
{-# OPTIONS -fglasgow-exts #-}
module Interpolate where
import Text.ParserCombinators.Parsec
import Language.Haskell.TH
interp s = do
parts <- case parse (do ps <- many interp_part; eof; return ps) s s of
Left err -> fail (show err)
Right x -> return x
[| concat $(return (ListE parts)) |]
interp_part =
choice
[do char '%'
choice
[do char '%'
return (LitE (StringL "%"))
,do char '{'
name <- many1 (noneOf "}")
char '}'
return (VarE (mkName name))
]
,do cs <- many1 (noneOf "%")
return (LitE (StringL cs))
]
_______________________________________________
Haskell-Cafe mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/haskell-cafe