2010-02-02 28 views
6

T4 là công cụ tạo mã "chính thức" cho C#/VB.NET. Nhưng F# doesn't support it (đây là từ tháng 4, nhưng tôi không thể tìm thấy bất kỳ đề cập mới hơn nào). Vậy cách tốt để tạo mã F # là gì?Tạo mã F #

EDIT:

Tôi muốn triển khai 2-3 finger trees trong F #. Tôi đã thực hiện chúng trong C#, vì vậy đây nên là một so sánh tốt đẹp. Các "chữ số" và các nút của cây có thể được biểu diễn dưới dạng mảng, vì vậy

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

Tuy nhiên, kích thước tối đa của các mảng là rất nhỏ, vì vậy nó sẽ được tốt đẹp để có

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 

để tránh kiểm tra giới hạn, vv

Nhưng sau đó viết tất cả các chức năng trên chữ số và nút bằng tay trở nên khó khăn hơn và tốt hơn là tạo chúng. Và một cách tiếp cận giống như T4 trông hoàn hảo cho nó ...

+0

tôi sẽ chỉ ném [này] (https://github.com/kerams/Templatus) ra khỏi đó. Đó là điều tôi đã tấn công gần đây. – nphx

Trả lời

7

Vì F # không hỗ trợ các công cụ tùy chỉnh trong trình khám phá giải pháp, bạn có thể đặt các tệp T4 trong dự án C# hoặc Visual Basic và chuyển hướng đầu ra của chúng đến dự án F # của bạn. Đây là cách bạn có thể làm điều đó với 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

Thật không may điều này sẽ thêm Module2.fs vào * bottom * của Library1.fsproj và thứ tự các tệp nguồn quan trọng trong F # :-( –

+1

"Vì F # không hỗ trợ các công cụ tùy chỉnh trong trình khám phá giải pháp", không chắc chắn ý bạn là gì rằng, khi chúng tôi sử dụng các công cụ tùy chỉnh trong các dự án F # của chúng tôi mọi lúc: FsYacc, FsLex, máy phát thử và các phần mở rộng MSbuild khác. không tự động cập nhật các tệp fsproj) hoặc thêm chúng ở dưới cùng và đảm bảo rằng các phụ thuộc được giải quyết bằng các tệp không được tạo tự động trước đó. – Abel

6

Nó phụ thuộc vào những gì bạn đang cố gắng làm. Trong khi đó là một cách tiếp cận không thực sự phù hợp để tạo mẫu theo cách mà nhiều ví dụ T4 hiển thị, nói chung tôi khuyên bạn nên thiết kế một "thư viện combinators" [1] để tạo mã hoặc các tác vụ lập trình hướng ngôn ngữ trong F #. Ý tưởng là thiết kế một số combinators để đại diện cho mã bạn đang cố gắng tạo ra, tạo ra văn bản nguồn F # từ các bộ phối hợp, sau đó biên dịch thông qua mã DOM.

Tuy nhiên, thường dễ dàng hơn khi viết một thông dịch viên cho các bộ phối hợp của bạn thay vì tạo mã.

ví dụ tốt của combinators trong F # là:

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

+1

Chỉ cần làm rõ - bạn đang đề xuất viết một thư viện tổ hợp kết quả đầu ra một cái gì đó giống như một hệ thống phân cấp công đoàn phân biệt có thể được dịch sang mã nguồn, phải không? Trái ngược với việc sử dụng FParsec để tạo mã, ý tôi là. Tôi chỉ muốn chắc chắn rằng không có một số tính năng ẩn của FParsec tôi đã không biết ... –

+0

Có, một nơi tốt để bắt đầu sẽ là một loại công đoàn có thể được dịch sang mã F #. FParsec chỉ là một ví dụ về một thư viện tổ hợp, nó không tạo ra mã F #, ít nhất là theo như tôi biết. – Robert

1

tôi đều đồng ý với Robert (mặc dù có chắc chắn một số tình huống mà sử dụng T4 từ F # có thể rất hữu ích). Dù sao, có lẽ sẽ thú vị khi biết lý do tại sao bạn có muốn tạo mã F # không? Sau đó, chúng tôi có thể có thể đề nghị một số giải pháp chức năng điển hình cho vấn đề :-).

+0

Đã thêm trường hợp sử dụng của tôi. –

+0

Tôi sợ rằng tôi không có ý tưởng hay về cách giải quyết vấn đề này một cách tao nhã - tôi đã gặp vấn đề tương tự một thời gian trước và không tìm được cách nào tốt. Ngay cả khi T4 (hoặc tương tự) hoạt động, nó vẫn sẽ phá vỡ tất cả việc kiểm tra kiểu chỉnh sửa thời gian F #, điều này sẽ khá khó chịu. Trong OCaml, điều này được giải quyết bởi Campl4 (http://en.wikipedia.org/wiki/Camlp4), nhưng không có điều tương đương với F # (và tôi sợ chỉ có nhu cầu giới hạn cho điều này, đặc biệt là so với các có thể cải thiện F #). –

+1

Về mảng so với tuples - Tôi nghĩ rằng hiệu suất của mảng (với kiểm tra giới hạn) có thể không phải là xấu (afterall, CLR có thể tránh kiểm tra trong nhiều trường hợp). Tuy nhiên, bạn cũng có thể thử giải pháp chức năng bằng cách sử dụng danh sách F # (nếu bạn có thể tránh lập chỉ mục trực tiếp), vì danh sách rất nhỏ nên khá nhanh (nhưng tôi không có bất kỳ số nào). –

3

Tôi đã xem xét các tùy chọn khác nhau và kết thúc cho nhu cầu tạo mã tương đối đơn giản và tĩnh của mình bằng tập lệnh * .fsx sử dụng TextWriter với fprintf để viết mã F # được tạo.

Tôi thực sự sử dụng FParsec cho một số công việc phân tích cú pháp, nhưng khi tôi không dịch từ một số cú pháp khác thành F #, hai phần có ít liên quan đến nhau.

+0

Điều này có thể là đủ. –

+1

Chắc chắn làm những người yêu thích đó mà không có bình luận để nói câu trả lời của tôi sai. Tôi học được rất nhiều từ họ! –

Các vấn đề liên quan