대수적 데이터 타입을 이용한 추상화와 클래스 시스템에 의한 상속의 비교
14016 단어 대수적 데이터 유형프로그래밍ADT추상화
그 때는, ReasonML에 있어서의 ADT=Algebraic Data Type(대수적 데이터형) 실장인 Variant
ReasonML의 Variant는 다음과 같으며 Rust라고 Enum에 해당합니다.
type animal =
| Dog
| Cat
| Duck;
이른바 직화라고 하는 것으로, 여러가지 형태의 합으로서 다른 형태를 표현하는 것 같은 느낌입니까.
그래서 이것을 어떻게 사용합니까?
let cry = () => switch(Dog) {
| Dog => "wan!"
| Cat => "nyaa!"
| Duck => "kuwa!!"
}
Js.log(cry()) // ただのconsole.logです。
위의 예라면
wan!
라고 출력됩니다.설명을 위해서, 이 예를 내 보았습니다만, 아마 그다지 맛을 느끼지 않는다고 생각하기 때문에, 조금 복잡한 예를 냅니다.
아마존 도서 구매
Amazon에서 책을 구입할 때 Kindle(전자책)과 Paperback(종이책)을 선택할 수 있네요.
그래서 두 가지를 모델링하면,
book <-> kindle paperback
라는 is-a
관계가 있는 것을 알 수 있습니다. (kindle is a book. paperback is a book)
(정확하게는, kindle is a kind of book.지도. 뭐 좋은가...)
이 때 book이라는 것은 kindle과 paperback의 추상적인 표현임을 알 수 있습니다.
즉, 아래와 같은 그래프의 상태입니다.
(이쪽 근처에 대해 잘 모르는 분은, 도마미지 영인씨에 의한 논문을 봐 주세요.→ "하늘" 정의 ~ 현대 분석 철학 및 메타 수리적 접근법 .이 분은 어렵다고 생각되고 있는 것을 쉽게 가르치는 천재입니다.)
그럼, 이런 관계를 클래스 시스템에서는 어떻게 표현하고 있었는가 하면,
class Book {
}
class Kindle extends Book {
}
class Paperback extends Book {
}
(JavaScript)
라는 상속을 사용합니다.
그리고, 「전자책에는 할인이 발생한다」라고 하는 사양이 있다고 합니다.
그 경우의 가격 계산의 논리를 생각해 봅시다.
class Book {
}
class Kindle extends Book {
constructor(price, discount) {
super()
this.price = price
this.discount = discount
}
calcPrice() {
return this.price * (1 - this.discount)
}
}
class Paperback extends Book {
constructor(price) {
super()
this.price = price
}
calcPrice() {
return this.price
}
}
되었다고 가정합니다.
그리고, 이 사양에 대해 토론했는데, 「책의 가격 계산은, 일률로 가격×할인율로 한다」라고 정해졌다고 합니다. (어쩐지 무리해...)
앞으로 책의 형태가 늘어나도 마찬가지로 로직으로 대응하고 싶기 때문에 '책'에 관한 일반적인 로직으로 취급하도록 수정했다고 합시다.
class Book {
constructor(price, discount) {
this.price = price
this.discount = discount
}
calcPrice() {
return this.price * (1 - this.discount)
}
}
class Kindle extends Book {
constructor(price, discount) {
super(price, discount) // Bookのコンストラクタの呼び出し
}
}
class Paperback extends Book {
constructor(price) {
super(price, 0) // 紙の本は、割引が発生しないから割引率は「0」
}
}
const kindle = new Kindle(100, 0.1)
console.log(kindle.calcPrice()) // 90
그럼 Variant에서 이것과 같은 일을하면 어떻게 될 것입니다.
먼저 방금전의 animal
형은 Dog
이나 Cat
의 추상형으로서 기능하고 있는 것을 생각해 주세요.
그 사고방식으로부터 가면,
type book =
| Kindle
| Paperback;
수 있습니다. 또한 Variant는 생성자를 받을 수 있으므로 거기에 가격과 할인율을 설정할 수 있습니다.
type book =
| Kindle(int, float) /* int: 値段 float: 割引率 */
| Paperback(int); /* int: 値段 */
그럼 , class 대신에 이것들을 Book
모듈에 넣어 줍니다.
가격 계산의 논리는 어떻게 될 것입니다.
let calcPrice = (x) => switch(x) {
| Kindle(price, discount) => Js.Int.toFloat(price) *. (1.0 -. discount) /* intのfloat変換が必要 */
| Paperback(price) => price
}
이렇게 쓸 수 있습니다.
이제 이전과 마찬가지로 계산 논리를 일반화하기 위해 클래스가 아닌 Book
모듈을 사용합시다.
Book
모듈에 형식 정의와 공유 논리를 포함시킵니다.
module Book = {
type book =
| Kindle(int, float) /* int: 値段 float: 割引率 */
| Paperback(int); /* int: 値段 */
let calcPrice = (x) => {
let calc = (price, discount) => Js.Int.toFloat(price) *. (1.0 -. discount)
switch(x) {
| Kindle(price, discount) => calc(price, discount)
| Paperback(price) => calc(price, 0.0) /* 紙の本は割引なし = 割引率0 */
}
}
}
이 모듈을 사용하도록, 방금 전의 구현을 고쳐 보겠습니다.
Js.log(Book.calcPrice(Book.Kindle(100, 0.1))) /* 90 */
처럼 표현할 수 있었습니다.
따라서 ADT는 추상화의 수단으로 사용할 수 있는 것이 아닐까 하는 비교였습니다.
Reference
이 문제에 관하여(대수적 데이터 타입을 이용한 추상화와 클래스 시스템에 의한 상속의 비교), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/oedkty/items/a0c01573b182bc8a9423
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
class Book {
}
class Kindle extends Book {
}
class Paperback extends Book {
}
class Book {
}
class Kindle extends Book {
constructor(price, discount) {
super()
this.price = price
this.discount = discount
}
calcPrice() {
return this.price * (1 - this.discount)
}
}
class Paperback extends Book {
constructor(price) {
super()
this.price = price
}
calcPrice() {
return this.price
}
}
class Book {
constructor(price, discount) {
this.price = price
this.discount = discount
}
calcPrice() {
return this.price * (1 - this.discount)
}
}
class Kindle extends Book {
constructor(price, discount) {
super(price, discount) // Bookのコンストラクタの呼び出し
}
}
class Paperback extends Book {
constructor(price) {
super(price, 0) // 紙の本は、割引が発生しないから割引率は「0」
}
}
const kindle = new Kindle(100, 0.1)
console.log(kindle.calcPrice()) // 90
type book =
| Kindle
| Paperback;
type book =
| Kindle(int, float) /* int: 値段 float: 割引率 */
| Paperback(int); /* int: 値段 */
let calcPrice = (x) => switch(x) {
| Kindle(price, discount) => Js.Int.toFloat(price) *. (1.0 -. discount) /* intのfloat変換が必要 */
| Paperback(price) => price
}
module Book = {
type book =
| Kindle(int, float) /* int: 値段 float: 割引率 */
| Paperback(int); /* int: 値段 */
let calcPrice = (x) => {
let calc = (price, discount) => Js.Int.toFloat(price) *. (1.0 -. discount)
switch(x) {
| Kindle(price, discount) => calc(price, discount)
| Paperback(price) => calc(price, 0.0) /* 紙の本は割引なし = 割引率0 */
}
}
}
Js.log(Book.calcPrice(Book.Kindle(100, 0.1))) /* 90 */
Reference
이 문제에 관하여(대수적 데이터 타입을 이용한 추상화와 클래스 시스템에 의한 상속의 비교), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/oedkty/items/a0c01573b182bc8a9423텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)