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
избегать проверки границ, и т.д.
Но затем запись всех функций на Цифре и Узле вручную становится более трудной, и лучше генерировать их. И подобный T4 подход выглядит идеально подходящим для него...
Поскольку F# не поддерживает пользовательские инструменты в solution explorer, вы можете поместить ваши 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();
}
}
#>
Это зависит от того, что вы пытаетесь сделать. Хотя такой подход не совсем подходит для генерации шаблонов, как показывают многие примеры T4, в целом я бы порекомендовал создать "библиотеку комбинаторов" [1] для генерации кода или задач программирования, ориентированных на язык, на F#. Идея заключается в том, чтобы спроектировать несколько комбинаторов для представления кода, который вы пытаетесь сгенерировать, генерируя исходный текст F# из комбинаторов, а затем компилируя его через код DOM.
Однако часто было бы проще просто написать интерпретатор для ваших комбинаторов, чем генерировать код.
Хорошими примерами комбинаторов в F# являются:
Я рассмотрел различные варианты, и в итоге для моих относительно простых и статичных потребностей в генерации кода я использовал сценарий * .fsx, который использует TextWriter с fprintf
для записи сгенерированного кода F #.
Я действительно использую FParsec для некоторой работы по синтаксическому анализу, но, поскольку я не перевожу какой-либо другой синтаксис в F #, эти две части мало связаны друг с другом.
Я в основном согласен с Робертом (хотя, безусловно, есть ситуации, когда использование T4 из F # может быть очень полезным). В любом случае, может быть, было бы интересно узнать , почему вы хотите сгенерировать код F #? Тогда мы могли бы предложить типичное функциональное решение проблемы :-).