Writing F# object expression in one single line

冷暖自知 提交于 2019-12-08 22:10:05

问题


As I was about to write a code generator for F#, I was wondering whether I could avoid stepping into the indentation mess by generating only one-line-values.

As part of this effort, I was considering how I could express Object Expressions in one single line, but couldn't succeed, except in Verbose Mode.

let Expr() = (let ToString = "ToString" in { new System.Object() with member this.ToString() = ToString; member this.GetHashCode() = ToString.GetHashCode()})

The issue is that I don't want to generate all my code in Verbose mode, this is a compatibility feature. Is there any other option?

Thanks a lot in advance for your insights!
François


The reason I ask for this is that I have to generate Object Expressions in arbitrary expressions and I would like to avoid to count the number of characters in the current line to compute how much I've to indent the next line.


回答1:


(Shameless plug) I maintain F# source code formatter which exposes APIs to pretty-print full F# 3.0 syntax. You have several options:

  • Implement your code generator using verbose mode and run the source code formatter APIs on the output. Then you don't have to worry about indentation and line break on verbose mode is very easy.

  • Implement your code generator using functional combinators. There are many combinators in FormatConfig module which you can copy and modify. F# indentation rule is clear; you can read more in this article.

  • You probably have an AST for pretty printing. If you prefer a lightweight solution, F# Compiler CodeDom has similar combinators for code generation.




回答2:


This is not strictly speaking an answer, but what is so bad about writing it with proper indentation? You can always make a list of the generated lines and add indentation in a separate step. This is how I usually generate code, even if the language (e.g. HTML) does not need indentation.

Why does generated code have to be illegible for humans? The proper indentation makes a review of the generated code easier and you can even use usual diff tools, if you for instance have the generated sources commited to source control.

At least in my experience proper indentation is actually far less difficult than one might think, especially when generating. Don't forget, that you have all the context at hand during the generation, so adding a level of indentation should be very easy.

let indent = List.map (sprintf "    %s")
[
    yield "let Expr() ="
    yield! [
        yield "let ToString = \"ToString\""
        yield "{"
        yield! [
            "new System.Object() with"
            "member this.ToString() = ToString"
            "member this.GetHashCode() = ToString.GetHashCode()"
        ] |> indent
        yield "}"
    ] |> indent
]


来源:https://stackoverflow.com/questions/20873206/writing-f-object-expression-in-one-single-line

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!