먼저 monoid를 설명하는 이와 같은 모나드에 대해 언어에 구애받지 않는 설명 을 사용하겠습니다 .
모노 이드는 파라미터로서 몇 가지 유형을 가지고 동일한 유형을 반환하는 함수의 (대략) 세트이다.
모나드 테이크 함수 (약) 세트이다 래퍼 인자로 타입과 동일한 타입 래퍼를 반환한다.
그것들은 정의가 아니라 설명입니다. 그 설명을 자유롭게 공격하십시오!
따라서 OO 언어에서 모나드는 다음과 같은 연산 구성을 허용합니다.
Flier<Duck> m = new Flier<Duck>(duck).takeOff().flyAround().land()
모나드는 포함 된 클래스가 아닌 해당 작업의 의미를 정의하고 제어합니다.
전통적으로 OO 언어에서는 클래스 계층 구조와 상속을 사용하여 이러한 의미를 제공합니다. 그래서 우리는 거라고 Bird
방법과 클래스를 takeOff()
, flyAround()
그리고 land()
, 오리는 사람들을 상속합니다.
그러나 우리는 날지 못하는 새들 때문에 어려움을 겪습니다 penguin.takeOff()
. 실패 하기 때문 입니다. 예외 처리 및 처리에 의지해야합니다.
또한 펭귄이 a라고 말하면 Bird
계층 구조가 여러 개인 경우와 같이 다중 상속에 문제가 발생 Swimmer
합니다.
본질적으로 우리는 클래스를 범주에 넣고 (범주 이론 녀석에게 사과와 함께) 개별 클래스가 아닌 범주별로 의미를 정의하려고합니다. 그러나 모나드는 계층 구조보다 훨씬 명확한 메커니즘처럼 보입니다.
이 경우 Flier<T>
위의 예와 같은 모나드 가 있습니다 .
Flier<Duck> m = new Flier<Duck>(duck).takeOff().flyAround().land()
... 우리는 결코 인스턴스화하지 않을 것 Flier<Penguin>
입니다. 우리는 정적 타이핑을 사용하여 마커 인터페이스와 함께 발생하지 않도록 할 수도 있습니다. 또는 런타임 기능 검사로 구제 할 수 있습니다. 그러나 실제로 프로그래머는 절대로 펭귄을 Flier에 넣지 말아야합니다. 같은 의미에서 결코 0으로 나누지 않아야합니다.
또한 더 일반적으로 적용됩니다. 전단지는 새일 필요는 없습니다. 예를 들어 Flier<Pterodactyl>
, 또는 Flier<Squirrel>
개별 유형의 의미를 변경하지 않은 경우.
유형 계층 구조가 아닌 컨테이너의 구성 가능한 함수로 의미를 분류하면 특정 계층 구조에 맞는 "종류, 유형, 종류"가 아닌 클래스의 오래된 문제를 해결합니다. 또한 클래스 Flier<Duck>
뿐만 아니라 여러 의미를 쉽고 명확하게 허용합니다 Swimmer<Duck>
. 클래스 계층과 동작을 분류하여 임피던스 불일치로 어려움을 겪고있는 것 같습니다. 모나드는 그것을 우아하게 처리합니다.
그래서 제 질문은 상속보다 구성을 선호하는 것과 같은 방식으로 상속보다 모나드를 선호하는 것이 합리적입니까?
(BTW 이것이 여기에 있는지 아니면 Comp Sci에 있는지 확실하지 않지만 실제 모델링 문제처럼 보입니다. 그러나 아마도 더 좋을 것입니다.)