문제

나는 최근에 언어를 배우고 기능적 프로그래밍에 대해 더 잘 알기 위해 OCAML 프로그래밍을 해왔습니다. 최근에, 나는 기존 유형 (내 구축 또는 내 자신의 하나)을 확장 할 수 있기를 원한다고 생각하기 시작했습니다.

type bexp =
  And of bexp * bexp
| Or of bexp * bexp
| Xor of bexp * bexp
| Not of bexp;;

이제이 유형에 NOP 변형을 추가하고 싶지만 상속과 같은 새로운 유형에서만 사용하기 위해서만 가정 해 봅시다. 이봐, 이것들은 대수 데이터 유형이어야합니까? 그렇다면 왜 :

type nbexp = bexp | Nop nbexp ;;

... 그러나 이것은 유효한 OCAML이 아니며 구문 오류를 제공합니다. 기본적으로, 내가하려고하는 것은 BEXP에 포함 된 모든 것을 포함하고 NOP를 추가하기를 원한다고 말하는 것입니다. 예를 들어, 생성자와 생성자를 사용한 경우 BEXP 유형인지 NBEXP 유형인지 확인할 방법이 없기 때문에 이것이 불가능하다고 생각합니다. (NBEXP를 복용하는 생성자 NOP도 문제가 될 수 있다고 생각합니다.)

OCAML에서 이와 같은 일을 할 수있는 방법이 있습니까? 그리고 이것은 Haskell에서 할 수있는 일입니다 (아마도 유형의 클래스와 함께)?

도움이 되었습니까?

해결책

흥미로운 해결책은 다형성 변이체를 사용하는 것입니다.

type bexp =
[ `And of bexp * bexp
| `Or of bexp * bexp
| `Xor of bexp * bexp
| `Not of bexp ];;

type nbexp = [ bexp | `Nop of nbexp ];;

다형성 변이체는 정상적인 변이보다 까다 롭지 만 유형의 확장을 허용합니다.

연장선을 사용하여 다형성 변형을 사용하여 발현 평가의 흥미로운 예는 OCAML 소스의 테스트 디렉토리에서 찾을 수 있습니다. SVN

다른 팁

자신이 올바르게 추측 할 때, 이것은 대수 유형에서는 불가능합니다. 나는 당신이 단순히 "상속 된"부분을 포장 할 수 있다는 ApoCalisp의 제안에 동의합니다. nbexp 자체 생성자로.

나는 대수 유형의 상속 부족이 그들의 놀라움의 일부라고 덧붙일 것입니다. 이것은 다음과 같은 표현을 의미합니다 And(foo, bar) 엄청나게 타이핑되고 해당 캐스팅 (위 또는 아래)은 유형 시스템에서 플레이 할 역할이 없습니다. 이것은 더 큰 안전성과 명확성을 모두 산출합니다. 물론 프로그래머가 필요로하는 경우가 필요합니다. bexp 의 일부 nbexp, 그러나 당신이 그것에 대해 생각한다면, 그것이 실제로 안전과 선명도가 실제로 실현되는 방식입니다.

이봐, 이것들은 대수 데이터 유형이어야합니까?

오른쪽. 그리고 대수 데이터 유형 태그 (일명 차별화 된) 노조 및 제품에 의해 건설됩니다. 당신이 원하는 것은 단지 (태그가없는) 노조입니다. ~ 아니다 대수 데이터 유형이며 Haskell은 지원하지 않습니다. OCAML에는 다형성 변이체가 있습니다 (다른 답변 참조).

타이핑 된 체계 태그가없는 노조를 지원하므로 확인할 수 있습니다.

업데이트 : OCAML에는 이제 확장 가능한 유형이 있습니다. http://caml.inria.fr/pub/docs/manual-ocaml/extn.html#sec246

여기에서 할 것입니다

type bexpr += Nop of bexpr
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top