2010-05-08 2 views
1
F 번호에

나는 System.Linq.Expression 인스턴스를 반환하는 기능을 가지고 . 내 첫 번째 생각은 반환 형식을 명시 적으로 #Expression으로 표시하는 것이지만 작동하지 않습니다. 반환 유형을 가장 일반적인 유형으로 수동으로 변환하는 것을 포함하지 않는보다 우아한 방법이 있습니까?F #의 반환 형식 강제 변환

감사합니다.

편집 : 답변 해 주셔서 감사합니다. 명시 적 리턴 유형 + 업 캐스팅 시나리오를 사용하겠습니다. 여기

답변

4

몇 가지 방법은 당신이 선호 할 수 있습니다

open System.Linq.Expressions 

type System.Object with 
    member this.ToExpression() : Expression = // explicit 
     match this with 
     | :? System.Int32 -> upcast Expression.Constant(this) // upcast 
     | :? System.Boolean -> Expression.Constant(this) :> _ // _ 
     | _ -> failwith "bad expression" 

명시 적으로 member 선언에 반환 유형을 명시함으로써, 당신은 신체, 예를 들어, 그것을 추론 할 수 _을 통해 "이 유형을 추측 해주십시오"또는 upcast 연산자를 사용하여 제약 조건에서 위로 캐스팅 할 유형을 추론 할 수 있습니다.

1

저는이 글을 쓰는 훨씬 더 우아한 방법이 있다고 생각하지 않습니다.

컴파일러에서는 match 표현식의 모든 분기가 동일한 반환 유형을 가지며 암시 적으로 강제 변환을 삽입하지 않아야합니다. upcast 키워드를 사용하여 대상 유형을 지정하지 않고 강제 변환을 삽입 할 수 있습니다.이 경우 컴파일러는 유형 정보와 같은 다른 정보를 사용하여 유형을 결정하므로 형식을 반복하지 않아도됩니다.

and System.Object with 
    member this.ToExpression() : Expression = 
    match this with 
    | :? System.Int32 -> upcast Expression.Constant(this) 
    | :? System.Boolean -> upcast Expression.Constant(this) 
    | :? Tml.Runtime.Seq as s -> upcast s.ToExpression() 
    | _ -> failwith "bad expression" 

표현식과 형식 주석 각각에 형식 주석과 upcast을 추가 했으므로 F # 컴파일러는 upcast이 결과를 Expression으로 강제 변환해야한다고 추론합니다. 함수를 호출 할 때 컴파일러가 암시 적 강제 변환을 삽입 유일한 장소입니다, 그래서 당신은 또한 다음과 같은 쓸 수 있습니다 (하지만 난 그게 더 좋은 있는지 확실하지 않다) :

어떤 이유
// Thanks to implicit coercions, we don't even need #type 
let expr (a:Expression) = a 

// and then for example: 
| :? System.Int32 -> Expression.Constant(this) |> expr 

, upcast이 키워드입니다 따라서 파이프 라이닝과 함께 사용할 수 없으므로 이와 같은 함수를 정의하면 몇 가지 이점이있을 수 있습니다.

1

엄밀히 상수의 유형이기 때문에

open System.Linq.Expressions 

let Constant obj = Expression.Constant(obj) :> Expression 

type System.Object with 
    member this.ToExpression() 
     match this with 
     | :? System.Int32 -> Constant(this) 
     | :? System.Boolean -> Constant(this) 
     | _ -> failwith "bad expression" 

이이 coersion을 제거하지 않고 내 의견으로는 (:) 너무 당신에게 입력을 조금 절약 할 수) 눈에 조금 더 나은 말하기 a '-> Expression은 두 경우 모두에서 작동합니다. 아래쪽은 당신이 사용하려고하는 각각의 Expression 팩토리 메소드에 대한 함수를 정의해야 할 필요가 있기 때문이다.