生成F#代码

时间:2010-02-02 08:10:50

标签: f# code-generation t4 code-templates

T4是C#/ VB.NET的“官方”代码生成引擎。但F# doesn't support it(这是从四月开始,但我找不到更新的提及)。那么生成F#代码的好方法是什么?

编辑:

我想在F#中实现2-3 finger trees。我已经在C#中实现了它们,所以这应该是一个很好的比较。树的“数字”和节点可以表示为数组,所以

type 't FingerTree = Empty | Single of 't | Deep of 't array * (('t FingerTree) array) lazy * 't array

但是,这些数组的最大大小非常小,所以很高兴

type 't Digit = Digit1 of 't | Digit2 of 't*'t | Digit3 of 't*'t*'t | Digit4 of 't*'t*'t*'t
type 't Node = Node2 of 't FingerTree * 't FingerTree | Node3 of 't FingerTree * 't FingerTree * 't FingerTree 
type 't FingerTree = Empty | Single of 't | Deep of 't Digit * ('t Node) lazy * 't Digit

避免边界检查等。

然后手动编写Digit和Node上的所有函数变得更加困难,并且最好生成它们。而类似T4的方法看起来很完美......

4 个答案:

答案 0 :(得分:7)

由于F#不支持解决方案资源管理器中的自定义工具,因此您可以将T4文件放在C#或Visual Basic项目中,并将其输出重定向到F#项目。以下是T4 Toolbox

的方法
<#@ template language="C#" hostspecific="True" debug="True" #>
<#@ output extension="txt" #>
<#@ include file="T4Toolbox.tt" #>
<#
    FSharpTemplate template = new FSharpTemplate();
    template.Output.Project = @"..\Library1\Library1.fsproj";
    template.Output.File = "Module2.fs";
    template.Render();
#>
<#+
class FSharpTemplate: Template
{
    public override string TransformText()
    {
#>
// Learn more about F# at http://fsharp.net

module Module2
<#+
        return this.GenerationEnvironment.ToString();
    }
}

#>

答案 1 :(得分:6)

这取决于你想做什么。虽然这种方法并不像许多T4示例所示的那样真正适合生成模板,但总的来说,我建议设计一个“组合器库”[1]用于F#中的代码生成或面向语言的编程任务。我们的想法是设计一些组合器来表示你试图生成的代码,从组合器生成F#源文本,然后通过代码DOM编译它。

然而,通常只为组合器编写解释器而不是生成代码会更容易。

F#中组合子的好例子是:

[1] http://en.wikipedia.org/wiki/Combinator_library

答案 2 :(得分:3)

我查看了各种选项,最后使用* .fsx脚本来完成我相对简单和静态的代码生成需求,该脚本使用带有fprintf的TextWriter来写出生成的F#代码。

我实际上使用FParsec进行一些解析工作,但由于我没有将其他语法翻译成F#,因此这两部分之间没什么关系。

答案 3 :(得分:1)

我主要赞同罗伯特(尽管在某些情况下使用F#中的T4可能非常有用)。无论如何,也许知道为什么你想要生成F#代码会有趣吗?然后我们可以建议一些典型的问题功能解决方案: - )。