|
View:
New views
6 Messages
—
Rating Filter:
Alert me
|
|
|
How to pretty print code efficientlyHi,
Currently I'm pretty printing code by building arrays of strings and calling indent. For example: instance JavaPrintableNamed AST.EnumeratedType where javaLinesNamed parentName (AST.EnumeratedType memberDefinitions) = [ "public enum " ++ asJavaId(parentName) , "{" ] ++ memberCodeLines ++ [ "}" , "" ] where memberCodeLines = indent $ javaLines memberDefinitions The indent function takes a list of strings and adds an indent to the beginning of every line. I can imagine this to be very inefficient as it builds many strings and concatenates them. In Ruby, I might do the same thing like this: class EnumeratedType < JavaPrintableNamed def writeTo(writer) writer.print "public enum " writer.puts self.asJavaId writer.puts "{" writer.indent do self.memberDefinitions.writeTo(writer) writer.puts end where above, the writer.indent takes care of the indent, and everything is appended to a stream, which doesn't seem so bad in terms of efficiency. I'm looking for a way to do something similar in Haskell. Anyone can give me a hand? Thanks -John _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@... http://www.haskell.org/mailman/listinfo/haskell-cafe |
|
|
Re: How to pretty print code efficientlyJohn Ky <newhoggy@...> wrote:
> Hi, > > Currently I'm pretty printing code by building arrays of strings and > calling indent. For example: > > instance JavaPrintableNamed AST.EnumeratedType where > javaLinesNamed parentName (AST.EnumeratedType memberDefinitions) = > [ "public enum " ++ asJavaId(parentName) > , "{" > ] ++ memberCodeLines ++ > [ "}" > , "" > ] > where > memberCodeLines = indent $ javaLines memberDefinitions > > The indent function takes a list of strings and adds an indent to the > beginning of every line. > > I can imagine this to be very inefficient as it builds many strings > and concatenates them. > rebuild, the second one is reused, due to sharing. So if you concatenate short strings to the front of a long string you're quite fine. But then, that isn't the answer you hoped for. > In Ruby, I might do the same thing like this: > > class EnumeratedType < JavaPrintableNamed > def writeTo(writer) > writer.print "public enum " > writer.puts self.asJavaId > writer.puts "{" > writer.indent do > self.memberDefinitions.writeTo(writer) > writer.puts > end > > where above, the writer.indent takes care of the indent, and > everything is appended to a stream, which doesn't seem so bad in > terms of efficiency. > > I'm looking for a way to do something similar in Haskell. > > Anyone can give me a hand? > bytestrings doesn't involve rebuilding the first string byte-by-byte, but constructs a superstructure denoting the concatenation. As for how to express it in code: I'd recommend a combination of a State monad to track the indentation, and the underused[1] Applicative interpretation of lists to concatenate stuff. >>= would function as concatenation of lines, getting the state, while the indent function would first set it to the new level, then execute the passed sub-action, and finally reset it to the old level. You're going to need a way to concatenate two strings without doing a line-break, too, of course. All in all, it's a splendid exercise in how to write custom monads. [1] Lists as ordered collections, not possibilities, that is, see e.g. the typeclassopedia ( http://www.haskell.org/sitewiki/images/8/85/TMR-Issue13.pdf ) -- (c) this sig last receiving data processing entity. Inspect headers for copyright history. All rights reserved. Copying, hiring, renting, performance and/or quoting of this signature prohibited. _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@... http://www.haskell.org/mailman/listinfo/haskell-cafe |
|
|
Re: How to pretty print code efficientlyOn Fri, Jul 3, 2009 at 6:45 PM, John Ky<newhoggy@...> wrote:
> Hi, > > Currently I'm pretty printing code by building arrays of strings and calling > indent. For example: > > instance JavaPrintableNamed AST.EnumeratedType where > javaLinesNamed parentName (AST.EnumeratedType memberDefinitions) = > [ "public enum " ++ asJavaId(parentName) > , "{" > ] ++ memberCodeLines ++ > [ "}" > , "" > ] > where > memberCodeLines = indent $ javaLines memberDefinitions > > The indent function takes a list of strings and adds an indent to the > beginning of every line. > > I can imagine this to be very inefficient as it builds many strings and > concatenates them. > > In Ruby, I might do the same thing like this: > > class EnumeratedType < JavaPrintableNamed > def writeTo(writer) > writer.print "public enum " > writer.puts self.asJavaId > writer.puts "{" > writer.indent do > self.memberDefinitions.writeTo(writer) > writer.puts > end > > where above, the writer.indent takes care of the indent, and everything is > appended to a stream, which doesn't seem so bad in terms of efficiency. > > I'm looking for a way to do something similar in Haskell. > > Anyone can give me a hand? > > Thanks > > -John > > > _______________________________________________ You may want to investigate the standard module Text.PrettyPrint.HughesPJ, which contains a number of (I assume fairly efficient) combinators for pretty printing. Alex _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@... http://www.haskell.org/mailman/listinfo/haskell-cafe |
|
|
Re: How to pretty print code efficientlyAchim Schneider <barsoap@...> wrote:
> As for how to express it in code: I'd recommend a combination of a > State monad to track the indentation, and the underused[1] Applicative > interpretation of lists to concatenate stuff. >>= would function as > concatenation of lines, getting the state, while the indent function > would first set it to the new level, then execute the passed > sub-action, and finally reset it to the old level. You're going to > need a way to concatenate two strings without doing a line-break, > too, of course. > Make that "Reader Monad" and "execute the passed sub-action with the new level inside a new monad" -- (c) this sig last receiving data processing entity. Inspect headers for copyright history. All rights reserved. Copying, hiring, renting, performance and/or quoting of this signature prohibited. _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@... http://www.haskell.org/mailman/listinfo/haskell-cafe |
|
|
Re: How to pretty print code efficientlyOn 4 jul 2009, at 05:13, Alexander Dunlap wrote:
> On Fri, Jul 3, 2009 at 6:45 PM, John Ky<newhoggy@...> wrote: >> Hi, >> >> Currently I'm pretty printing code by building arrays of strings >> and calling >> indent. For example: >> >> instance JavaPrintableNamed AST.EnumeratedType where >> javaLinesNamed parentName (AST.EnumeratedType memberDefinitions) = >> [ "public enum " ++ asJavaId(parentName) >> , "{" >> ] ++ memberCodeLines ++ >> [ "}" >> , "" >> ] >> where >> memberCodeLines = indent $ javaLines memberDefinitions >> >> The indent function takes a list of strings and adds an indent to the >> beginning of every line. >> >> I can imagine this to be very inefficient as it builds many strings >> and >> concatenates them. >> >> In Ruby, I might do the same thing like this: >> >> class EnumeratedType < JavaPrintableNamed >> def writeTo(writer) >> writer.print "public enum " >> writer.puts self.asJavaId >> writer.puts "{" >> writer.indent do >> self.memberDefinitions.writeTo(writer) >> writer.puts >> end >> >> where above, the writer.indent takes care of the indent, and >> everything is >> appended to a stream, which doesn't seem so bad in terms of >> efficiency. >> >> I'm looking for a way to do something similar in Haskell. >> >> Anyone can give me a hand? >> >> Thanks >> >> -John >> >> >> _______________________________________________ > > You may want to investigate the standard module > Text.PrettyPrint.HughesPJ, which contains a number of (I assume fairly > efficient) combinators for pretty printing. I second that. Also, there is uulib which has a pretty printing module that's quite similar: http://hackage.haskell.org/packages/archive/uulib/0.9.10/doc/html/UU-PPrint.html I think both packages are based on the paper "The Design of a Pretty- printing Library" which can be found at http://www.cs.chalmers.se/~rjmh/Papers/pretty.ps Not only do they provide abstractions for things like indentation, concatenation in different forms, etc., but they also are more efficient than a naive implementation using lists. -chris -chris _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@... http://www.haskell.org/mailman/listinfo/haskell-cafe |
|
|
Re: How to pretty print code efficientlyHi all,
Thanks everyone for the help. The HughesPJ module works well for me. Cheers, -John On Mon, Jul 6, 2009 at 3:49 AM, Chris Eidhof <chris@...> wrote:
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@... http://www.haskell.org/mailman/listinfo/haskell-cafe |
| Free embeddable forum powered by Nabble | Forum Help |