2011-07-30 2 views
11

Ocaml에는 정의 된 유형을 확장하는 간단한 구조/스타일이 있습니까? 우리는 부울 유형이있는 경우Ocaml에서 정의 된 유형을 재사용하고 확장하십시오.

말은,

bool2 = True | False 

이제 우리는 세 값 로직을 확장 할. OCaml의에서이 같은 Bool2를 다시 정의보다 더 우아한 하나가 : 그것 뿐이다

type bool2 = [ `True | `False ] 
type bool3 = [ bool2 | `Third_one ] 

:

bool3 = True | False | ThirdOne 

답변

8

나는 다형성 변이의 과도한 사용에 대해 조언 할 것입니다. 그들은 종이에서 멋지게 보이지만 더 유연한 추론 및 하위 유형 지정은 언제든지 당신을 물러나게 할 것입니다. 다형성 변형을 사용할 때마다 모든 사용에 정확한 구속 유형 표현이 주석으로 지정되도록 노력합니다.

이전 코드로 돌아가서 자연스럽게 수정하는 것이 좋습니다. 확장 성을 염두에두고 코드를 작성한 경우, 특히 유형의 _ -pattern을 피하면 컴파일러는 두 개의 생성자 만 있다고 가정하는 모든 장소에 대해 경고합니다. 타입 수정에 대한이 컴파일러 피드백은 프로그램을 수정하는 데 도움이되는 기계적인 도움이되므로 매우 유용합니다.

이러한 일을하는 방법은 물론 몇 가지 단점이 있습니다. 그 중 하나는 유형 정의를 수정 한 다음 각 유스 케이스를 수정하는 것이 일반적인 컴파일 테스트 실습과 잘 작동하지 않을 수 있다는 것입니다. 대규모 코드베이스에서 그렇게하면 프로젝트를 컴파일하기 전에해야 할 일이 많을 것입니다 깨끗하게 다시 (따라서 테스트 할 수 있습니다). 수정 사항을 여러 버전의 패치로 버전 관리 시스템으로 나눌 수는 있지만, 이는 중개 된 커밋 된 상태가 컴파일되지 않는다는 것을 의미하며 이는 그리 만족스럽지 않습니다. 또 다른 가능성은 런타임 오류 (| Third_one -> assert false)를 추가하기 위해서만 해당 위치를 변경하는 것입니다. 그러면 컴파일 가능한 코드가 있으며 런타임에 응용 프로그램 테스트 중 발생하는 오류를 수정할 수 있습니다. 하지만 여전히 정적 컴파일러 피드백은 코드 유지 관리에 도움이된다고 생각합니다.

대수 데이터 형식을 "확장 대수 데이터 형식"type bool3 = New | Old of bool2에 래핑하는 옵션도 있습니다.이 데이터 형식은 마틴 (Martin) 응답의 주석으로 제공되는 링크에서 설명합니다. 이것은 컴파일을 중단하지 않고 한 데이터 유형에서 다른 데이터 유형으로 전환하는 좋은 방법 일 수 있지만, 특히 더 많은 확장을 서로 위에 겹쳐 놓으면 고통 스럽습니다.

물론 상황에 따라 실제로 필요한 것은 정적으로 안전하고 컴파일, 실행 및 테스트가 용이 한 방식으로 코드 수정 대신 코드 추가로 데이터 유형을 확장하는 방법 일 것입니다. 런타임시 효율적입니다. 이것은 Expression Problem의 인스턴스이며, 그 중 여러 솔루션 인 다형성 변형이 그 중 하나입니다. 그러나 일반적인 경우에는 코드 추가 만하는 유연성이 추가로 필요하지 않으며 관련 언어 기능이 추가로 복잡해질 필요가 없습니다. 따라서 분명히 큰 변형이 아닌 일반 언어의 변형 유형을 사용하는 것이 좋습니다. 다르게 행동하십시오.

추 신 : 다형성 변이체와 관련하여 표현 문제와의 관계에서 의무 용지는 Jacques Garrigue의 Code reuse through polymorphic variants입니다.

14

다형성 변종이 기능을 제공합니다.

다형성 변형에 대한 또 다른 유용한 바로 가기가 있습니다. 그들은 쉽게 혼동 오류 메시지가 발생할 수

let is_bool2 = function 
    #bool2 -> true 
    | `Third_one -> false 

다형성 변종은주의해서 사용해야합니다 : 패턴 매칭에서, # 앞에 유형 이름을 사용합니다. 어쨌든 원래 유형 bool2이 다형성 변형이 아니면 다음과 같이 두 유형의 결합이 이루어집니다. 이제 bool2를 가정 해 보자하는 핵심 유형 bool이다, 고전적인 변형을 사용하여 우리의 정의는 다음과 같습니다

 
type bool3 = Bool of bool | Third_one 

패턴 매칭에서, 컴파일러가 타입 주석을 필요로하지 않고, 모든 경우가 포함되어 있는지 확인합니다. 다음과 같이 보입니다 :

 
match x with 
| Bool true -> ... 
| Bool false -> ... 
| Third_one -> ... 
+1

bool2가 라이브러리에 정의 된 유형이라고 상상해보십시오. 명백하게 다형성 변이체를 통한 제안 된 접근법은 bool2의 원래 정의를 단일 다형성에서 다형성으로 재 정의해야합니다. 그래서 내 질문에 대한 간단한 직접 회신 : 아니, 우리 bool3 확장 할 bool2 다시 정의해야합니다. 맞지, 마틴? 감사. – zell

+0

아, http://stackoverflow.com/questions/1746743/extending-an-existing-type-in-ocaml에서 아주 비슷한 질문을 발견했습니다. – zell

1

현재 진행중인 작업에 따라 Extensible Variant Types도 유용 할 수 있습니다. 자세한 정보 및 사용 사례 here.

type bool = .. 
type bool += 
    | True 
    | False 

(* Elsewhere *) 
type bool += 
    | Third_one 
관련 문제