2011-02-27 3 views
11

OCaml을 처음으로 살펴본 결과, F # 및 Haskell과 배경이 약간 있습니다. 이와 같이, 많이 익숙한 모양이지만, 하나가 아닌 것은 "열린"및 "닫힌"노동 조합의 개념입니다 (백틱과 [< 구문).Ocaml의 개방형 및 폐쇄 형 유니온 타입

이러한 기능은 얼마나 유용하고 자주 사용됩니까?

+1

다형성 변형을 사용하는 이유에 대한 자세한 내용은 여기 answer : http://stackoverflow.com/questions/1746743/extending-an-existing-type-in-ocaml – aneccodeal

답변

17

gasche's answer has good advice. 개방적이고 폐쇄 된 노동 조합에 대해 좀 더 설명 할 것입니다.

먼저 기본 변형 (백틱 없음)과 다형성 변형 (백틱 포함)의 두 가지 종류를 구분해야합니다.

  • 기본 변종은 생식있다 : 당신이 다른 모듈 M1M2에서 같은 생성자 이름을 가진 두 가지 유형을 정의 할 경우, 서로 다른 유형이있다. M1.FooM2.Foo은 다른 생성자입니다. `Foo은 어디에서든 항상 동일한 생성자입니다.
  • 다형성 변형은 기본 변형이 할 수있는 모든 것을 할 수 있습니다. 그러나 위대한 힘은 엄청나게 복잡해 지므로 필요하고 신중할 때만 사용해야합니다.

다형성 변형 유형은 해당 유형이 가질 수있는 생성자를 설명합니다. 그러나 많은 다형성 변형 유형은 완전히 알려지지 않았습니다. 유형 변수는 (행) 유형 변수를 포함합니다. 빈 목록 []을 고려하십시오. 유형은 'a list이며 더 구체적인 유형을 'a에 할당하는 많은 컨텍스트에서 사용할 수 있습니다. 예 :

# let empty_list = [];; 
val empty_list : 'a list = [] 
# let list_of_lists = [] :: empty_list;; 
val list_of_lists : 'a list list = [[]] 
# let list_of_integers = 3 :: empty_list;; 
val list_of_integers : int list = [3] 

행 유형 변수에도 동일하게 적용됩니다. [> … ]으로 작성된 공개 유형에는 값을 사용할 때마다 더 많은 생성자를 포함하도록 인스턴스화 할 수있는 행 변수가 있습니다. 생성자는 해당 유형의 모든 사용을 의미하지 않는 형태로 나타나기 때문에

# let foo = `Foo;; 
val foo : [> `Foo ] = `Foo 
# let bar = `Bar;; 
val bar : [> `Bar ] = `Bar 
# let foobar = [foo; bar];; 
val foobar : [> `Bar | `Foo ] list = [`Foo; `Bar] 

그냥 모든 생성자를 허용한다. [> …]은 유형에 최소한 이러한 생성자가 있어야하며 이중 유형 [< …]에는 유형에 최대로 이러한 생성자가 있어야한다고 명시되어 있습니다.이 기능을 고려 :

# let h = function `Foo -> `Bar | `Bar -> `Foo;; 
val h : [< `Bar | `Foo ] -> [> `Bar | `Foo ] = <fun> 

hFooBar 및 처리 만 가능하므로 입력 종류가 다른 생성자를 허용하지 않는 경우; 그러나 hFoo 만 허용하는 유형으로 호출하는 것이 좋습니다. 반대로 hFoo 또는 Bar을 반환 할 수 있으며 h이 사용 된 모든 문맥은 FooBar을 허용해야합니다 (다른 사람도 허용 할 수 있음).

폐쇄 형은 유형에 최소 및 최대 생성자 요구 사항이 일치 할 때 발생합니다. 예를 들어, h가 동일한 입력 및 출력 유형이 있어야합니다 제약 조건을 추가 할 수 있습니다 :

# let hh : 'a -> 'a = function `Foo -> `Bar | `Bar -> `Foo;; 
val hh : [ `Bar | `Foo ] -> [ `Bar | `Foo ] = <fun> 

청산 종류는 거의 형식 유추에서 자연적으로 발생하지 않습니다. 대부분의 경우 여기처럼 사용자 주석의 결과입니다. 다형성 주석을 사용할 때, 명명 된 유형을 정의하고 적어도 모든 최상위 함수에 사용하는 것이 좋습니다. 그렇지 않으면 추론 된 유형은 생각보다 조금 더 일반적 일 수 있습니다. 버그가 거의 발생하지는 않지만, 유형 오류가있을 때보 다 나중에 진단되어 도움이되는 부분을 찾기가 어려울 수있는 매우 오랜 오류 메시지가 생성되는 경우가 있습니다.

polymorphic variant tutorial in the Ocaml manual을 읽고 작업하여 (예 : 톱니 바퀴에서 예제를 다시 입력하고 각 단계를 이해하기 위해 조금 놀아 드리는 것이 좋습니다).

+0

꽤 고급스러운 것 같아서이 주제에 대해 더 생각해야 할 것입니다. 그러나 자세한 답변을 해주셔서 감사드립니다. –

11

당신은 "코드 다형성 변종 다시"자크 Garrigue의를 읽을 필요가 :

http://www.math.nagoya-u.ac.jp/~garrigue/papers/fose2000.html

다형 변형의 문제들이 형식 유추가 다형성에 오류가 당신에게 많은 도움이되지 수 있도록 유연하고 있다는 것입니다 변종 코드. 예를 들어, 하나의 생성자 이름을 잘못 입력하면 컴파일러에서 오류를 표시 할 수 없으며 일반 생성자와 약간 다른 유형과 철자가 틀린 유형 만 유추합니다. 장애가 발생한 코드를 변종에 대한 엄격한 가정 (폐쇄 패턴 일치)이있는 기능과 다루기 힘든 오류 메시지와 결합하려고하면 나중에 오류가 발견됩니다.

다형성 변형 사용자에 대한 조언은 유형 확인을 제어하기 위해 주석을 대량 사용하는 것입니다. 다형성 변형을 입력으로 사용하거나 출력 할 때마다 함수에 변형 부품의 정확한 유형을 주석으로 추가해야합니다. 이것은 대부분의 추론 이슈로부터 당신을 보호 할 것이며, 구성 할 수 있고 프로그램에 대한 추론을 도와 줄 수있는 표현형 세트를 만들 것을 강요합니다.

+0

감사합니다. 지금 종이 읽는 중. –