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的方法看起来很完美......
答案 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#中组合子的好例子是:
答案 2 :(得分:3)
我查看了各种选项,最后使用* .fsx脚本来完成我相对简单和静态的代码生成需求,该脚本使用带有fprintf
的TextWriter来写出生成的F#代码。
我实际上使用FParsec进行一些解析工作,但由于我没有将其他语法翻译成F#,因此这两部分之间没什么关系。
答案 3 :(得分:1)
我主要赞同罗伯特(尽管在某些情况下使用F#中的T4可能非常有用)。无论如何,也许知道为什么你想要生成F#代码会有趣吗?然后我们可以建议一些典型的问题功能解决方案: - )。