Aracılığıyla paylaş


Kod teklifleri (F#)

Bu konuda açıklar kod teklifleri, üretmek ve F# kod deyimleri ile programlı olarak çalışmanıza olanak sağlayan bir dil özelliği. F# kodunu temsil eden bir soyut sözdizimi ağacı oluştur Bu özelliği sağlar. Soyut sözdizimi ağacı çapraz geçiş ve uygulamanızın gereksinimlerine göre işlenir. Örneğin, ağaç F# kod oluşturun veya kodu başka bir dilde oluşturmak için kullanabilirsiniz.

Teklif edilen ifadeler

A deyimi tırnak işareti içine bir F# ifade kodunuzda bu programın bir parçası olarak derlenmemiş emin şekilde sınırlanmış, ancak bunun yerine F# ifade temsil eden bir nesne derlenir. Teklif edilen bir ifade iki yoldan birini kullanarak işaretleyebilirsiniz: bilgilerini yazın veya türü bilgi. Tür bilgileri dahil etmek istiyorsanız, semboller kullanın<@ ve @> teklif edilen deyim sınırlandırmak için. Tür bilgileri gerekmiyorsa, semboller kullanın <@@ ve @@>. Aşağıdaki kod, typed ve untyped teklifleri gösterir.

open Microsoft.FSharp.Quotations
// A typed code quotation.
let expr : Expr<int> = <@ 1 + 1 @>
// An untyped code quotation.
let expr2 : Expr = <@@ 1 + 1 @@>

Büyük ifade ağacı tersine çevirme türü bilgileri eklemezseniz daha hızlıdır. Sonuç türü tırnak içinde yazılan sembollerle ifade Expr<'T>, type parametresi F# derleyicisi 's türü kesmesi algoritması tarafından belirlendiği biçimde ifade türünün bulunduğu. Kod teklifleri türü bilgisi olmadan kullandığınızda, teklif edilen ifade türünün genel olmayan türü olan ifade. Arayabileceğiniz Ham özellikte yazılı Expr untyped elde etmek için sınıf Expr nesne.

F# ifade nesneleri programlı olarak izin statik yöntemler vardır Expr kullanmadan sınıf ifadeleri tırnak içinde.

Not kod teklif tam deyimi içermelidir. İçin bir let bağlama, örneğin, iki tanım ilişkili adı ve bağlamanın kullandığı ek bir ifade gerekir. Ayrıntılı sözdiziminde, bunu izleyen bir ifadesidir in anahtar sözcüğü. En üst düzey bir modül, bu modülü yalnızca sonraki deyimde olduğu halde bir teklife kesinlikle gerekli.

Bu nedenle, aşağıdaki deyim geçerli değil.

// Not valid:
// <@ let f x = x + 1 @>

Ancak, aşağıdaki ifadeler geçerlidir.

// Valid:
<@ let f x = x + 10 in f 20 @>
// Valid:
<@ 
    let f x = x + 10
    f 20
@>

Kod teklifleri kullanmak için bir alma bildirimi eklemeniz gerekir (kullanarak open anahtar sözcüğünü) açılır Microsoft.FSharp.Quotations ad.

F# PowerPack değerlendirme ve F# ifade nesnelerini çalıştırmak için destek sağlar.

İfade türü

Örneğini Expr F# ifade türünü gösterir. Hem genel hem de genel olmayan Expr türleri F# kitaplık belgelerinde belgelenmiştir. Daha fazla bilgi için, bkz. Microsoft.FSharp.Quotations İsim Uzayı (F#) ve Quotations.Expr Sınıfı (F#).

Splicing işleçleri

Splicing, program aracılığıyla veya başka bir kod tırnak oluşturulan ifadelerle hazır kod teklifleri birleştirmenize olanak sağlar. % Ve %% işleçleri F# ifade nesne kodu tırnak eklemek etkinleştirin. Kullandığınız % yazılı bir teklif; yazılı expression nesnesini eklemek için işleç kullandığınız %% türlenmemiş bir tırnak untyped ifade nesne eklemek için işleci. Her iki tekli önek operatörleri işleçlerdir. Bu nedenle, expr türü bir untyped ifadesidir Expr, aşağıdaki kodu geçerli değil.

<@@ 1 + %%expr @@>

Ve expr yazılı bir teklif türü Expr<int>, aşağıdaki kodu geçerli değil.

<@ 1 + %expr @>

Örnek

Dd233212.collapse_all(tr-tr,VS.110).gifDescription

Aşağıdaki örnek kod teklifleri F# kodu deyim nesnenin yerleştirin ve sonra ifade eden F# kodu yazdırmak için kullanımını göstermektedir. Bir işlev println tanımlı bir işlevi içeren print bir F# expression nesnesini görüntüleyen (türü Expr) kolay bir biçimde. Etkin desenleriyle vardır Microsoft.FSharp.Quotations.Patterns ve Microsoft.FSharp.Quotations.DerivedPatterns ifade nesneleri çözümlemek için kullanılabilecek modülleri. Bu örnek, bir F# ifade ortaya çıkabilecek olası desenleri içermez. Herhangi bir desen eşleştirme joker desene tetikler tanınmayan (_) kullanılarak oluşturulur ve ToString yöntemi, hangi, üzerinde Expr yazın, eşleşme İfadenizde eklemek için etkin desen bildiğiniz olanak sağlar.

Dd233212.collapse_all(tr-tr,VS.110).gifKod

module Print
open Microsoft.FSharp.Quotations
open Microsoft.FSharp.Quotations.Patterns
open Microsoft.FSharp.Quotations.DerivedPatterns

let println expr =
    let rec print expr =
        match expr with
        | Application(expr1, expr2) ->
            // Function application.
            print expr1
            printf " "
            print expr2
        | SpecificCall <@@ (+) @@> (_, _, exprList) ->
            // Matches a call to (+). Must appear before Call pattern.
            print exprList.Head
            printf " + "
            print exprList.Tail.Head
        | Call(exprOpt, methodInfo, exprList) ->
            // Method or module function call.
            match exprOpt with
            | Some expr -> print expr
            | None -> printf "%s" methodInfo.DeclaringType.Name
            printf ".%s(" methodInfo.Name
            if (exprList.IsEmpty) then printf ")" else
            print exprList.Head
            for expr in exprList.Tail do
                printf ","
                print expr
            printf ")"
        | Int32(n) ->
            printf "%d" n
        | Lambda(param, body) ->
            // Lambda expression.
            printf "fun (%s:%s) -> " param.Name (param.Type.ToString())
            print body
        | Let(var, expr1, expr2) ->
            // Let binding.
            if (var.IsMutable) then
                printf "let mutable %s = " var.Name
            else
                printf "let %s = " var.Name
            print expr1
            printf " in "
            print expr2
        | PropertyGet(_, propOrValInfo, _) ->
            printf "%s" propOrValInfo.Name
        | String(str) ->
            printf "%s" str
        | Value(value, typ) ->
            printf "%s" (value.ToString())
        | Var(var) ->
            printf "%s" var.Name
        | _ -> printf "%s" (expr.ToString())
    print expr
    printfn ""


let a = 2

// exprLambda has type "(int -> int)".
let exprLambda = <@ fun x -> x + 1 @>
// exprCall has type unit.
let exprCall = <@ a + 1 @>

println exprLambda
println exprCall
println <@@ let f x = x + 10 in f 10 @@>

Dd233212.collapse_all(tr-tr,VS.110).gifÇıktı

fun (x:System.Int32) -> x + 1
a + 1
let f = fun (x:System.Int32) -> x + 10 in f 10

Örnek

Dd233212.collapse_all(tr-tr,VS.110).gifDescription

Üç etkin desenler de kullanılabilir ExprShape modülü daha az etkin desenlerle ifade ağaç için. Bu etkin desenler bir ağaç Gez istiyorsanız ancak çoğunda düğümleri ve tüm bilgileri gerekmez yararlı olabilir. Bu desenleri kullandığınızda, herhangi bir F# ifade aşağıdaki üç desenlerden birini eşleşir: ShapeVar ifade bir değişken ise ShapeLambda deyimi bir lambda ifadesi ise veya ShapeCombination başka bir şey ifade ise. Önceki kod örneği etkin desenler kullanılarak ifade ağaç Gez, olası tüm F# ifade türlerini işlemesi için çok daha fazla desenleri kullanmak zorunda ve kodunuzu daha karmaşık olacaktır. Daha fazla bilgi için bkz. ExprShape.ShapeVar|ShapeLambda|ShapeCombination Etkin Deseni (F#).

Aşağıdaki kod örneği, daha karmaşık çapraz geçişlerine için temel olarak kullanılabilir. Bu kodda, ifade için bir işlev çağrısı içerir ifade ağaç oluşturulan add. SpecificCall herhangi bir çağrı algılamak için kullanılan etkin desen add ifadesi ağacında. Bu etkin desen çağrısına bağımsız değişkenleri atar exprList değeri. Bu durumda vardır yalnızca iki böylece bunlar çekilen ve işlev bağımsız yinelemeli olarak adlandırılır. Sonuçları bir çağrı temsil eden bir kod tırnak içine eklenen mul splice işlecini kullanarak (%%). println Önceki örnekteki işlevi, sonuçları görüntülemek için kullanılır.

Değişikliği sonuçta elde edilen deyim, tek değişiklik, bu nedenle active desen dallarındaki kodu aynı ifade ağaç yalnızca yeniden üretir add için mul.

Dd233212.collapse_all(tr-tr,VS.110).gifKod

module Module1
open Print
open Microsoft.FSharp.Quotations
open Microsoft.FSharp.Quotations.DerivedPatterns
open Microsoft.FSharp.Quotations.ExprShape

let add x y = x + y
let mul x y = x * y

let rec substituteExpr expression =
    match expression with
    | SpecificCall <@@ add @@> (_, _, exprList) ->
        let lhs = substituteExpr exprList.Head
        let rhs = substituteExpr exprList.Tail.Head
        <@@ mul %%lhs %%rhs @@>
    | ShapeVar var -> Expr.Var var
    | ShapeLambda (var, expr) -> Expr.Lambda (var, substituteExpr expr)
    | ShapeCombination(shapeComboObject, exprList) ->
        RebuildShapeCombination(shapeComboObject, List.map substituteExpr exprList)

let expr1 = <@@ 1 + (add 2 (add 3 4)) @@>
println expr1
let expr2 = substituteExpr expr1
println expr2

Dd233212.collapse_all(tr-tr,VS.110).gifÇıktı

1 + Module1.add(2,Module1.add(3,4))
1 + Module1.mul(2,Module1.mul(3,4))

Ayrıca bkz.

Diğer Kaynaklar

F# dil başvurusu