2010-03-16 2 views
3

몇 가지 열거 형의 문자열 표현을 열거 형 값으로 변환하려고합니다.인수가 형식이지만 형식화 된 값이 아닌 함수를 작성하는 방법은 무엇입니까?

Enum.Parse(typeof<FontStyle>,"Bold") |> unbox<FontStyle> 

을하지만 지금 난 유형 및 문자열 매개 변수가 어디에 함수를 작성하려면 : 그것은 구체적인 형태로 문자열을 변환하는 것은 쉽다. 내가 쓸 수있는 최선의 일입니다

> let s2e (_: 'a) s = Enum.Parse(typeof<'a>,s) |> unbox<'a>;; 
val s2e : 'a -> string -> 'a 
> s2e FontStyle.Regular "Bold";; 
val it : FontStyle = Bold 

이 같은 것을 쓸 수있는 옵션이 있지만 첫 번째 인수로 유형 자체?

답변

4

함수는 반환 된 열거 형의 형식이 될 단일 형식 매개 변수를 사용해야합니다. 그러나 코드의 어느 곳에서도 사용되지 않는 "가짜"매개 변수를 사용하여 유형을 지정하지 않아도됩니다. 예를 들어 defaultof<SomeType>을 호출 할 때와 같은 표기법을 사용하여 함수를 호출 할 때 실제 유형 매개 변수를 지정할 수 있습니다.

다음 수정 기능 (I 코드에 '와'대체 SO 코드 포맷터 혼란 피하기 위해)만을 반환 유형에서 발생하는 단일 유형 파라미터를 취

> let parseEnum<´a> s = Enum.Parse(typeof<´a>,s) |> unbox<´a>;; 
val parseEnum : string -> ´a 

함수를 호출 명시 적으로 유형을 지정해야합니다

> parseEnum<FontStyle> "Bold";; 
val it : FontStyle = Bold 

귀하의 솔루션이 꽤 가까웠다 - 유일한 변화는 타입 추론을 안내하는 증인 값을 제공의 명시 적으로 대신 유형 매개 변수를 지정할 수 있다는 것입니다.

+0

토마스, 감사합니다. – ssp

1

토마스의 대답은 좋습니다.

let parseEnum<'t,'u when 't:enum<'u>> s = System.Enum.Parse(typeof<'t>, s) :?> 't 
(parseEnum "Class" : System.AttributeTargets) 

지금 int 때문에 컴파일시 실패합니다 (parseEnum "Test" : int)를 호출하면 열거되지 않습니다 : 또한, 당신이 사용되는 것을 무의미한 유형 매개 변수를 방지하기 위해 F #의 enum 제약 조건을 적용 할 수 있습니다.

편집

우리가 실제로 기본 유형 'u와 아무것도하지 않기 때문에 SSP는 코멘트에서 지적 하듯, 우리가, F #의 열거 제약의 모든 기능이 필요하지 않다. struct 제약 조건 형식 인수로 System.Enum 자체를 사용 방지 함을

let parseEnum<'t when 't :> System.Enum and 't : struct> s = 
    System.Enum.Parse(typeof<'t>, s) :?> 't 

참고 : 그것은 단지 하나의 형식 매개 변수를 가지고 있기 때문에 쉽게 사용할 수 있습니다.

+0

정말 흥미 롭습니다. F # 유형 시스템이 그러한 유스 케이스에 대해 동적 다운 캐스트를 사용하지 않는다고 말하는 방법이 있습니까? 런타임 캐스트를 사용하는 것이 가장 좋은 방법은 아니지만, 큰 입력 스트림에서 시간이 많이 소요된다고 생각합니다. 답변의 변화에 ​​따라 – ssp

+0

는 것을에게 등을 작성할 수 있습니다 ... |> parseEnum : parseEnum <'a when 'a:> 열거>의 = Enum.Parse (대해서 typeof <'a>, S)하자> '는 – ssp

+0

@ssp -이?을 다운 캐스트 (또는 언 박싱과 같은 동등한 작업)를 피할 방법이 없습니다. 'System.Enum.Parse' 메쏘드는 객체를 반환하기 때문에 결과 타입으로 동적으로 변환되어야합니다. – kvb

관련 문제