2017-11-23 1 views
1

목록에서 주어진 입력 요소의 인접 어커런스가 하나가되는 목록을 반환하는 간단한 함수를 작성했습니다.값 제한 및 형식 유추

let rec reduce l = 
match l with 
| []    -> [] 
| [x]    -> [x] 
| x::(y::_ as xs) -> if x = y then 
          reduce xs 
         else 
          x::(reduce xs) 


# reduce [1;1;2;2;2;3;3;4;3;3;3];; 
- : int list = [1;2;3;4;3]. 
# reduce [’a’;’a’;’a’;’b’];; 
- : char list = [’a’; ’b’]. 
# reduce [];;    // The case 
- : ’a list = [] 

빈 목록을 제외하고 모두 예상대로 작동합니다. [] 입력. 고소인이 말합니다 오류 FS0030 : 값 제한. 나는 documentation을 통해 현상에 대해 더 잘 이해하려고 노력했지만, 제대로 이해하기위한 기술을 아직 가지고 있지는 않습니다. 일반 함수가 []과 함께 대소 문자를 지정해야하는 이유는 무엇입니까? 형식 유추없이 단순히 []이보고 된 결과를 가져올 수 없습니까? 그리고 마지막으로, 그러한 사건을 포착하기 위해 기능이 어떻게 구조화되어야 하는가?

+0

문제는 '[]'이 (가) '목록'이지만 컴파일러가 'a'가 무엇인지 알아 내야한다는 것입니다. –

+0

@JohnPalmer에게 감사드립니다. – Worice

답변

2

John이 의견에서 말했듯이 문제는 []이 목록의 유형에 대한 힌트를 컴파일러에 제공하지 않는다는 것입니다. 다른 모든 경우에는 정수 문자 목록을 알지만, 유형을 알 수 없습니다.

알 수없는 제네릭 형식이 포함 된 F # 코드를 실행할 수 없으므로 코드를 실행하고 일반 목록을 가져올 방법이 없습니다. 코드를 실행할 때 모든 형식을 완전히 지정해야합니다.

당신은 유형을 해결하기 위해 여러 가지 방법으로 유형 주석을 제공 할 수

: 이제 일반적인 코드가 다른 일반적인 내부에 있기 때문에,

reduce ([] : int list) 
(reduce [] : int list) 
(reduce:int list -> _) [] 

당신은 또한 컴파일 다른 일반적인 기능에 호출을 래핑 수를

let foo() = reduce [] 

을하지만 지금 당신이 같은 문제가 - foo를 호출 할 때 유형을 지정해야하거나, 컴파일러는 컨텍스트, 예로부터 추론 할 수 있어야한다 : 순서에 따라 유형이 필요 기능을 사용할 수 작성하는 경우 1 :: foo()

+0

Tomas 감사합니다. 당신의 직접적인 설명 때문에, 이제는 분명히이 문제에 대해 더 잘 이해하게되었습니다. – Worice