2010-07-12 4 views
4

SQL (http://github.com/kolosy/furious)에 대해 F # dsl을 쓰고 있습니다.F # 인용 부호 안에 변수 삽입

SELECT 문은 다음과 같이 보일 것이다 :

type person = { 
    personId: string 
    firstname: string 
    lastname: string 
    homeAddress: address 
    workAddress: address 
    altAddresses: address seq 
} 
and address = { 
    addressId: string 
    street1: string 
    zip: string 
} 

let (neighbor: person seq) = 
    db.Yield <@ Seq.filter (fun p -> p.homeAddress.zip = '60614') @> 

명백한 (바보) 질문은 ... 내가 인용 변수화 어떻게해야합니까?

내가처럼 somehting 경우

let z = "60614" 
let (neighbor: person seq) = 
    db.Yield <@ Seq.filter (fun p -> p.homeAddress.zip = z) @> 

다음 z 정적 속성 접근 ( PropertyGet(None, String z, []))로 해결됩니다. 따옴표만으로 변수 바인딩/바인딩을 가져올 수있는 무언가가 필요합니다. 아이디어?

답변

6

견적 내 장점 아니지만, 여기의 차이를 체크 아웃 :

let z = "60614" 
let foo = <@ List.filter (fun s -> s = z) @> 
printfn "%A" foo 

let foo2 = 
    let z = z 
    <@ List.filter (fun s -> s = z) @> 
printfn "%A" foo2 

나는 어쩌면 가진 생각 'Z'표현의 로컬 수는 값이 캡처되는 의미가 아니라 속성 참조보다.

+0

:

open Microsoft.FSharp.Quotations let rec expand e = match e with // Extract value of global 'let' bound symbols | Patterns.PropertyGet(None, pi, []) -> Expr.Value(pi.GetValue(null, [| |]), e.Type) // standard recursive processing of quotations | ExprShape.ShapeCombination(a, b) -> ExprShape.RebuildShapeCombination(a, b |> List.map expand) | ExprShape.ShapeLambda(v, b) -> Expr.Lambda(v, expand b) | ExprShape.ShapeVar(v) -> Expr.Var(v) 

는 그런 다음 값 대신 PropGet이 포함 된 견적을 얻기 위해 다음과 같은 기록 할 수 있습니다 와우. 청초한, 고마워. 얼마나 안정 될까요? 에서처럼, 문서화되지 않은 기능입니까 아니면 현재 반복의 동작입니까? 인용문을 통해 파고 드는 따뜻하고 모호한 것들을 많이 얻지는 않습니다. – kolosy

+1

안정적인 기능이라고 생각합니다. 최상위 레벨에서 선언 된 이름은 모듈의 값 (정적 클래스의 속성)이지만 로컬 이름은 값입니다. 도. 오. – Brian

+0

. 오케이, 그렇기 때문에 테스트 용 하네스가 작성된 방법 때문에 문제가되었습니다. 말이된다. – kolosy

4

브라이언이 작성한 것 외에도 저는 글로벌 let 바인딩 값에 대한 액세스 인코딩이 꽤 안정적이며 앞으로도 계속해서 PropGet으로 인코딩 될 것입니다.

이것은 번역자에서이 사례를 명시 적으로 지원하고 간단한 사전 처리 단계를 추가하여 이러한 속성 값을 가져올 수 있음을 의미합니다. 이것은 ExprShape을 사용하여 수행 할 수 있습니다 (4 가지 경우를 사용하여 인용문을 완전히 탐색 할 수 있음). 이렇게하면 DSL이 일반적인 경우도 지원할 수 있습니다.

다음 함수는 인용을 통과하고 자신의 가치와 글로벌 let들에 대한 액세스를 대체

let z = 5 
let eOrig = <@ Seq.filter (fun p -> p = z) [ 1 .. 10 ]@> 
let eNice = expand eOrig 
관련 문제