2017-02-21 1 views
2

일반 열거 형 값을 사용하고 기본 정수 값을 두 배로하는 F # 함수를 작성하고 싶습니다. 다행스럽게도 enum을 정수로 변환하는 int이라는 내장 함수가 있으므로 쉽게 처리 할 수 ​​있어야합니다. 맞습니까? 여기 내 첫 번째 시도이다 :Enum 형식의 F # 형식 제약

let doubler (value : 't when 't : enum<int>) = 
    2 * (int value) 

슬프게도,이 다음과 같은 컴파일러 메시지가 발생합니다

Program.fs이 (2,10) : 경고 FS0064 :이 구조는 코드보다 덜 일반적인되게 형식 주석으로 표시됩니다. 변수 유형 '이 (가)'int '유형으로 제한되었습니다.

Program.fs (2,10) : 오류 FS0071 : 형식 유추 변수에 기본 형식 'int'를 적용 할 때 형식 제약 조건이 일치하지 않습니다. 유형 'int' 은 CLI enum 유형이 아닙니다. Program.fs (1,28) - (1,42)도 참조하십시오. 추가 유형 제한을 추가한다고 생각하십시오.

내가 뭘 잘못하고 있니? F #의 일반 열거 형 값에서 기본 정수를 추출하는 더 좋은 방법이 있습니까?

+0

'enum'은 값을 표현으로 변환합니다. 컴파일러는 당신을 위해 제약 조건을 넣을 것입니다. 아래를 참조하십시오. – s952163

답변

1

EnumToValue이 필요합니다.

open FSharp.Core.LanguagePrimitives 

let doubler xEnum = 
     2 * EnumToValue(xEnum) 

type ColorEnum =  
      | Red=0 
      | Yellow=1 
      | Blue=2 

let blue = ColorEnum.Blue 

doubler blue 
//val it : int = 4 

그리고 당신이 doubler의 유형 서명 살펴보면 :

발 더블 : xEnum : 'A -> INT'는 : 열거 첫 번째 오류에 관한

을, int은 특수한 의미에서 함수이기도합니다. 당신이 지적으로, 당신은 열거에 기본 유형의 제약 조건을 사용하지만,이 경우 유형에 대한 명시 적, 그래서 혼란이 없다 할 수 있습니다

let double2 (x:'T when 'T:enum<int32>) = 
    2 * EnumToValue(x) 

불행히도 당신은 여전히 ​​int으로 캐스팅 할 수 없습니다가 EnumToValue을 사용하지 마십시오. 컴파일러 문제 일 수도 있고 다른 문제 일 수도 있습니다. 아마도 EnumToValue의 내부가 힌트를 줄 수 있을까요?

+0

완벽 해. 고마워. 그래도 내 코드가 작동하지 않는 것은 이상한 것처럼 보입니다. – brianberns

+0

@brianberns 일반 Enum이 없기 때문입니다 (제 생각 엔). 제약 조건을 원한다면'let doubl2 (x : 'T when'T : enum ) ='라고 말할 필요가있다. 이렇게하면 x가 Enum의 한 유형일뿐입니다. 그리고 당신은 여전히'int' 문제에 부딪 힐 것입니다. 나는 그 근본 원인을 모른다. – s952163

+0

뜻은 'enum '과 같은 것이 없다는 것입니다. 물론 타입 시그니처를 훔쳐서 명시 적으로 만들 수 있습니다 : 'tripler (xEnum :'a when : a : enum <_>) = 3 * EnumToValue (xEnum)'. 하지만 컴파일러가 없어도 컴파일러에서 예를 들어 char 열거 형을 사용하면 오류가 발생합니다. 솔직히 말해서 F #에서 열거 형을 사용할 필요가 없었습니다. DU가있을 수 있기 때문입니다. 아마도 명령 줄 인수를 제외하고 말입니다. – s952163