2010-02-02 14 views
6

टी -4 "आधिकारिक" के लिए सी #/VB.NET कोड पीढ़ी इंजन है। लेकिन F# doesn't support it (यह अप्रैल से है, लेकिन मुझे कोई नया उल्लेख नहीं मिला)। तो एफ # कोड उत्पन्न करने का एक अच्छा तरीका क्या है?उत्पन्न एफ # कोड

संपादित करें:

मैं एफ # में 2-3 finger trees लागू करना चाहते हैं। मैंने पहले ही उन्हें सी # में लागू किया है, इसलिए यह एक अच्छी तुलना होना चाहिए। "अंक" और पेड़ की नोड्स सरणियों के रूप में प्रतिनिधित्व किया जा सकता है, तो

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 

सीमा की जाँच, आदि से बचने के लिए

लेकिन फिर हाथ से अंक और नोड पर सभी कार्यों लेखन अधिक मुश्किल हो जाता है, और यह उन्हें उत्पन्न करने के लिए बेहतर है। और एक टी -4 की तरह दृष्टिकोण यह के लिए एकदम सही लग रहा है ...

+0

मैं सिर्फ [इस] (https://github.com/kerams/Templatus) फेंक देंगे वहाँ बाहर। यह हाल ही में मैंने कुछ हैक किया है। – nphx

उत्तर

7

क्योंकि एफ # समाधान एक्सप्लोरर में कस्टम टूल्स का समर्थन नहीं करता है, तो आप अपनी टी 4 फाइलें सी # या विजुअल बेसिक प्रोजेक्ट में रख सकते हैं और अपने आउटपुट को अपने एफ # प्रोजेक्ट पर रीडायरेक्ट कर सकते हैं। यहाँ कैसे आप 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

दुर्भाग्यवश यह Module2.fs को लाइब्रेरी 1.fsproj के * नीचे * में जोड़ देगा और स्रोत फ़ाइलों का क्रम F # :-( –

+1

में महत्वपूर्ण है "क्योंकि F # समाधान एक्सप्लोरर में कस्टम टूल का समर्थन नहीं करता है", सुनिश्चित नहीं है कि आपका क्या मतलब है कि, हम अपने एफ # प्रोजेक्ट्स में हर समय कस्टम टूल्स का उपयोग करते हैं: एफएसवाईएसीसी, एफएसएलएक्स, टेस्ट जेनरेटर और अन्य एमएसबिल्ड एक्सटेंशन। मूल्यांकन के क्रम के संबंध में, या तो * .fsproj फ़ाइलों में सही क्रम में फ़ाइलों को शामिल करें (और fsproj फ़ाइलों को स्वचालित रूप से अपडेट न करें), या उन्हें नीचे जोड़ें और सुनिश्चित करें कि निर्भरताएं पूर्व-गैर-जेनरेट की गई फ़ाइलों द्वारा हल की जाती हैं। – Abel

6

यह निर्भर करता है आपके क्या करने की कोशिश कर रहा है क्या। हालांकि यह एक दृष्टिकोण है कि जिस तरह से कई टी -4 उदाहरणों से पता चलता में पैदा टेम्पलेट्स के लिए वास्तव में उपयुक्त नहीं है, सामान्य रूप में मैं [1] कोड पीढ़ी या भाषा उन्मुख एफ # में प्रोग्रामिंग कार्यों के लिए एक "combinators पुस्तकालय" को डिजाइन करने की सिफारिश करेंगे है। विचार है कि कुछ संयोजकों को उस कोड का प्रतिनिधित्व करने के लिए डिज़ाइन करना है जिसे आप उत्पन्न करने का प्रयास कर रहे हैं, संयोजनकर्ताओं से F # स्रोत टेक्स्ट उत्पन्न करते हैं, फिर इसे कोड DOM के माध्यम से संकलित करते हैं।

हालांकि अक्सर यह आसान हो बस बल्कि कोड के उत्पादन की तुलना अपने combinators के लिए एक दुभाषिया लिखने के लिए होगा।

एफ # में combinators का अच्छा उदाहरण हैं:

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

+1

बस स्पष्ट करने के लिए - आप एक संयोजक पुस्तकालय लिखने का सुझाव दे रहे हैं जो एक भेदभाव वाले संघ पदानुक्रम की तरह कुछ आउटपुट करता है जिसे स्रोत कोड में अनुवादित किया जा सकता है, है ना? कोड उत्पन्न करने के लिए FParsec का उपयोग करने के विरोध में, मेरा मतलब है। मैं बस यह सुनिश्चित करना चाहता हूं कि FParsec की कुछ छिपी हुई विशेषता नहीं है I ... –

+0

हां, शुरू करने के लिए एक अच्छी जगह एक यूनियन प्रकार होगी जिसका अनुवाद एफ # कोड में किया जा सकता है। एफपीआरसीईसी एक संयोजक पुस्तकालय का सिर्फ एक उदाहरण था, यह कम से कम जहां तक ​​मुझे पता है, एफ # कोड उत्पन्न नहीं करता है। – Robert

1

मैं ज्यादातर रॉबर्ट से सहमत (हालांकि निश्चित रूप से कुछ स्थितियों में, जहां देखते हैं एफ # से टी 4 का उपयोग करना बहुत उपयोगी हो सकता है)। वैसे भी, शायद यह पता करने के लिए दिलचस्प होगा क्यों आप एफ # कोड उत्पन्न करना चाहते हैं? फिर हम समस्या के कुछ सामान्य कार्यात्मक समाधान का सुझाव दे सकते हैं :-)।

+0

मेरा उपयोग केस जोड़ा गया। –

+0

मुझे डर है कि मेरे पास इस सुंदरता को हल करने का कोई अच्छा विचार नहीं है - मुझे कुछ समय पहले इसी तरह की समस्या थी और मुझे कोई अच्छा तरीका नहीं मिला। भले ही टी 4 (या इसी तरह) ने काम किया हो, फिर भी यह सभी एफ # संपादन-समय प्रकार की जांच को तोड़ देगा, जो काफी परेशान होगा। ओकैमल में, यह कैम्पल 4 (http://en.wikipedia.org/wiki/Camlp4) द्वारा हल किया जाता है, लेकिन एफ # के लिए कोई समतुल्य बात नहीं है (और मुझे डर है कि इसके लिए केवल सीमित आवश्यकता है, खासकर अन्य के साथ तुलना में संभव एफ # सुधार)। –

+1

सरणी बनाम tuples के बारे में - मुझे लगता है कि सरणी का प्रदर्शन (सीमाओं की जांच के साथ) खराब नहीं हो सकता है (बाद में, सीएलआर कई मामलों में चेक से बच सकता है)। हालांकि, आप एफ # सूचियों का उपयोग करके कार्यात्मक समाधान का प्रयास भी कर सकते हैं (यदि आप सीधे अनुक्रमण से बच सकते हैं), क्योंकि बहुत छोटी सूचियां काफी तेज होनी चाहिए (लेकिन मेरे पास कोई संख्या नहीं है, दुर्भाग्यवश)। –

3

मैंने विभिन्न विकल्पों पर चारों ओर देखा, और * .fsx स्क्रिप्ट का उपयोग करके मेरी अपेक्षाकृत सरल और स्थैतिक कोड-जनरेटिंग आवश्यकताओं के लिए समाप्त हुआ जो जेनरेट एफ # कोड लिखने के लिए fprintf के साथ टेक्स्टवाइटर का उपयोग करता है।

मैं वास्तव में कुछ पार्सिंग काम के लिए एफपीआरसीईसी का उपयोग करता हूं, लेकिन जैसा कि मैं कुछ अन्य वाक्यविन्यास से एफ # में अनुवाद नहीं कर रहा हूं, दोनों टुकड़ों को एक दूसरे के साथ बहुत कम करना है।

+0

यह पर्याप्त हो सकता है। –

+1

निश्चित रूप से उन उत्तरों को प्यार करें जो बिना किसी टिप्पणी के मुझसे प्यार करते हैं कि मेरे जवाब में क्या गलत है। मैं उनसे बहुत कुछ सीखता हूं! –