2011-02-09 2 views
4

F # 인용구로 그립을 잡으려고 몇 시간을 보냈지만 약간의 도로 블록을 발견했습니다. 나의 요구 사항은 차별화 된 유니온 타입에서 간단한 함수 (정수, +, -, /, *)를 취하고 결국 C 코드를 생성하는 데 사용될 식 트리를 생성하는 것이다. 인용문을 '직접'기능을 사용하여 사용하는 것이 가능하다는 것을 알고 있습니다.F # 인용문 - 값으로 표시된 함수 호출로 이동

제 문제는 표현식 트리가 "값"으로 끝나는 것 같습니다. 그 값으로 넘어가는 방법을 파악할 수 없습니다.

제 질문은 이 상황에서 실제로 가능한지 여부입니다. 고려할 가치가있는 다른 접근법이 있습니까?

type FuncType = 
| A of (int -> int -> int) 
| B 
| C 

[<ReflectedDefinition>] 
let add x y = x + y 


let myFunc1 = A (fun x y -> x + y) 
let myFunc2 = A add 

let thefunc expr = 
    match expr with 
    | A(x) -> 
     <@ x @> 
    | _ -> 
     failwith "fail" 

printfn "%A" (thefunc myFunc1) // prints "Value (<fun:[email protected]>)" 
printfn "%A" (thefunc myFunc2) // prints "Value (<fun:[email protected]>)" 
printfn "%A" <@ fun x y -> x + y @> // generates usable expression tree 

답변

7

인용문 구문인용 된 F # 코드를 나타냅니다. 즉, <@ x @>과 같은 것을 쓰면, 인용문은 단지 Value 대소 문자를 포함하며, 지정된 값을 가진 것을 인용 부호로 묶어 지정합니다. 변수가 따옴표 밖에 정의 된 경우 변수는 자동으로 값으로 대체됩니다.

당신은 명시 적으로 <@ .. @> 또는 ReflectedDefinition로 표시되고 인용에 이름에 의해 참조 (예를 들면 <@ add @>하지만 예를 let f = add in <@ f @>에 대한) 기능의 사용을 인용 한 코드의 견적을 얻을 수 있습니다.

스 니펫이 제안하는 것을 수행하려면 FuncType에 견적을 저장해야합니다 (작성한 람다 함수도 따옴표로 묶어서 해당 본문을 가져올 수 있도록). 예 :

type FuncType = 
    | A of Expr<int -> int -> int> 
    | B | C 

[<ReflectedDefinition>] 
let add x y = x + y 

let myFunc1 = A <@ fun x y -> x + y @> 
let myFunc2 = A <@ add @> 

let thefunc expr = 
    match expr with 
    | A(x) -> x 
    | _ -> failwith "fail" 

ReflectedDefinition으로 표시된 기능의 경우에도 작동합니다. 당신이 좋아하는 무언가를 추가 할 필요가 함수의 본문을 추출하려면 (당신이 매개 변수에 대한 함수의 인수를 대체해야합니다, 그러나 이것은 당신에게 몇 가지 아이디어를 줄 것이다) : 당신의 좋은 답변

match expr with 
| Lambdas(_, body) -> 
    match body with 
    | Call(_, mi, _) when Expr.TryGetReflectedDefinition(mi) <> None -> 
     let func = Expr.TryGetReflectedDefinition(mi) 
     match func with 
     | Some(Lambdas(_, body)) -> 
      // 'body' is the quotation of the body 
     | _ -> failwith "Not supported function" 
    | _ -> failwith "Not supported function" 
| _ -> failwith "Not supported expression" 
+0

감사합니다, 그것은이 인용문을 이해하는 데 많은 공백을 메웠고 앞으로 나에게 한 길을 제시해주었습니다. – Jimmy