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

Reply via email to