生成 F# 代码

发布于 2024-08-20 03:10:12 字数 903 浏览 14 评论 0原文

T4 是 C#/VB.NET 的“官方”代码生成引擎。但是F# 不支持它(这是从四月份开始的,但我不能'找不到任何新的提及)。那么生成 F# 代码的好方法是什么?

编辑:

我想实现 2-3 手指树 F#。我已经用 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 的方法看起来非常适合它......

T4 is the "official" code generation engine for C#/VB.NET. But F# doesn't support it (this is from April, but I couldn't find any newer mentions). So what is a good way to generate F# code?

EDIT:

I want to implement 2-3 finger trees in F#. I already have implemented them in C#, so this should be a nice comparison. The "digits" and nodes of the tree can be represented as arrays, so

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

However, the maximum size of these arrays is very small, so it'd be nice to have

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

to avoid bounds checking, etc.

But then writing all functions on Digit and Node by hand becomes more difficult, and it's better to generate them. And a T4-like approach looks perfect for it...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

狼性发作 2024-08-27 03:10:12

由于 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();
    }
}

#>

Because F# doesn't support custom tools in solution explorer, you can place your T4 files in a C# or Visual Basic project and redirect their output to your F# project. Here is how you can do it with 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();
    }
}

#>
坐在坟头思考人生 2024-08-27 03:10:12

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

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

F# 中组合器的良好示例包括:

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

It depends what your trying to do. While it's an approach that's not really suitable for generating templates in the way many T4 examples show, in general I would recommend designing a "combinators library" [1] for code generation or language oriented programming tasks in F#. The idea is to design some combinators to represent the code you're try to generate, generating F# source text from combinators, then compiling this via the code DOM.

However often it would be easier simply to write an interpreter for your combinators rather than generating code.

Good examples of combinators in F# are:

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

幼儿园老大 2024-08-27 03:10:12

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

实际上,我确实使用 FParsec 进行一些解析工作,但由于我没有将其他语法转换为 F#,因此这两部分彼此几乎没有关系。

I looked around at various options, and ended up for my relatively simple and static code-generation needs using a *.fsx script that uses a TextWriter with fprintf to write out the generated F# code.

I actually do use FParsec for some parsing work, but as I'm not translating from some other syntax into F#, the two pieces have little to do with each other.

忘年祭陌 2024-08-27 03:10:12

我基本上同意 Robert 的观点(尽管在某些情况下使用 F# 中的 T4 确实非常有用)。不管怎样,也许了解为什么想要生成 F# 代码会很有趣?然后我们也许可以建议一些典型的功能解决方案来解决这个问题:-)。

I mostly agree with Robert (though there are certainly some situations where using T4 from F# could be very useful). Anyway, maybe it would be interesting to know why do you want to generate F# code? Then we could maybe suggest some typical functional solution to the problem :-).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文