2013-02-24 11 views
3

F # 튜플에 대한 형식 추가 메서드를 만들려고합니다. 이 코드는 잘 컴파일 :F # 튜플 확장 메서드를 만들 수 있습니까

type System.Tuple<'a, 'b> with 
    member this.ToParameter name = 
     match this with 
     | this -> sprintf "%s=%O,%O" name (this.Item1, this.Item2) 

을 그러나, 나는이 방법을 호출하려고하면

printfn "%s" (("cat", 2).ToParameter("test")) 

내가 말하는 오류 얻을 "이 필드, 생성자 또는 멤버를 'ToParameter'정의되지 않았습니다." 내가 표현을 통해 올려 놓으면, 비주얼 스튜디오에서

typedefof<'a * 'b>.FullName 
(1, 2).GetType().FullName 

:

let a = 1, 2 

그것은이를보고 인터프리터에서 다음과 같은 표현은 일부 System.Tuple'2의 형태로서 자신의 유형을보고 int * int 형식입니다. 이 유형을 늘리려고하거나 동등한 'a *'b 일 경우 오류가 발생합니다.

F # 튜플에 대한 일반적인 기능을 추가 할 수 있습니까?

+1

확장 메서드 (함수가 아닌)를 만드는 특별한 이유는 무엇입니까? – pblasucci

+0

ToParameter on may 유형을 호출 할 수 있기를 원합니다. 나는 IEnumerable <'a>, 문자열 등을 위해 작동하는 기능을 가지고있다. 이러한 모든 유형을 처리 할 단일 함수를 작성하려면 복싱과 리플렉션에 의존해야합니다. 각 유형에 대해 다른 메소드를 작성할 수는 있지만 API가 읽기 쉽지 않습니다. –

+1

오버로드 된 메소드로 타입을 생성하는 것이 아닌 - t.ToParameter() 대신'utils.ToParameter (t)'를 사용하는 것이 좋을 것입니다. –

답변

4

귀하의 질문에 대한 답변은 제가 유사한 질문에 준 답변과 거의 같습니다. here. 즉, 형식 확장이 작동하지 않는 이유는 "System.Tuple<_,...,_>은 튜플의 인코딩 된 형식이며 컴파일러에서 사용하는 정적 표현이 아니기 때문입니다. 사양에서 6.3.2 Tuple Expressions을 참조하십시오."

당신의 유형 확장을 사용하려면 첫 번째 상자에해야 다음 튜플 값 캐스트 : 제외

let tuple = box ("cat", 2) :?> System.Tuple<string,int> 
printfn "%s" (tuple.ToParameter("test")) 

을 : 또한 당신의 유형 확장에 약간의 구문 오류를 가지고 있습니다, 그것은해야 :

type System.Tuple<'a, 'b> with 
    member this.ToParameter name = 
     match this with 
     | this -> sprintf "%s=%O,%O" name this.Item1 this.Item2 //removed parens around Item1 and Item2 
0

당신은 C# 스타일의 확장 방법을 사용하지만 ToParameter의 당신의 정의에 오류를 발견 할 수 있습니다, 인수 카레해야합니다

open System.Runtime.CompilerServices 

[<Extension>] 
type TupleExtensions() = 
    [<Extension>] static member ToParameter((a, b), name) = sprintf "%s=%O,%O" name a b 

printfn "%s" (("cat", 2).ToParameter("test")) 

System.Tuple을 사용하는 이유는 컴파일 타임에 .NET 튜플과 F # 구문 튜플이 다른 유형으로 취급되기 때문입니다. 이것은 이후 버전의 컴파일러에서 변경 될 수 있습니다.

관련 문제