차별적 노동 조합이 기능적 프로그래밍과 관련되는 이유는 무엇입니까?


30

OO 프로그래밍의 오랜 세월 동안 나는 차별적 노동 조합이 무엇인지 이해했지만, 결코 그들을 그리워하지 않았습니다. 최근에 C #에서 일부 기능 프로그래밍을 수행해 왔으며 이제는 계속 사용하기를 바랍니다. 차별적 노조의 개념이 기능적 / OO 이분법과는 상당히 독립적 인 것처럼 보이기 때문에 이것은 당황 스럽다.

차별화 된 노동 조합이 OO보다 유용하게 사용할 수있는 기능적 프로그래밍에 내재 된 것이 있습니까? 아니면 문제를 "더 나은"방식으로 분석하도록 강요함으로써 표준을 올렸고 이제는 더 나은 것을 요구합니다 모델?


표현 문제 en.wikipedia.org/wiki/Expression_problem 은 관련이있을 수 있습니다
xji

그것은 실제로 질문에 대한 적절한 답변이 아니기 때문에 대신 의견으로 답장을하지만 Ceylon 프로그래밍 언어에는 공용체 유형이 있으며 다른 OO / 혼합 패러다임 언어 인 TypeScript와 Scala가 내 마음에 들어옵니다. 또한 Java 언어 열거 형은 일종의 차별적 조합의 구현으로 사용될 수 있습니다.
Roland Tepp

답변:


45

차별 조합은 실제로 패턴 일치와 함께 빛을 발하며 사례에 따라 다른 동작을 선택합니다. 그러나이 패턴은 순수한 OO 원칙과 근본적으로 반대 입니다.

순수 OO에서 동작의 차이는 유형 (객체) 자체에 의해 정의되고 캡슐화되어야합니다. 따라서 패턴 일치와 동등한 것은 객체 자체에 단일 메소드를 호출하는 것입니다. 그런 다음 다른 동작을 정의하기 위해 해당 하위 유형에 의해 오버로드됩니다. 패턴 매칭이 수행하는 외부에서 객체의 유형을 검사하는 것은 반 패턴으로 간주됩니다.

근본적인 차이점은 함수형 프로그래밍에서 데이터와 동작이 분리되고 데이터와 동작이 OO로 캡슐화된다는 것입니다.

이것이 역사적인 이유입니다. C #과 같은 언어는 점점 더 많은 기능을 통합하여 클래식 OO 언어에서 다중 패러다임 언어로 발전하고 있습니다.


6
차별화 된 공용체 / 합계 유형은 상속 트리 나 인터페이스를 구현하는 여러 클래스와 다릅니다. 많은 종류의 값을 가진 하나의 유형입니다. 또한 캡슐화를 막지 않습니다. 클라이언트는 여러 종류의 값이 있다는 것을 알 필요가 없습니다. 빈 노드이거나 값과 다른 노드에 대한 참조 일 수있는 링크 된 목록을 고려하십시오. 합계 유형이 없으면 어쨌든 값과 참조에 대한 변수를 가짐으로써 구별 된 공용체를 해킹하지만 null 참조가있는 객체를 빈 노드로 취급하고 값 변수를 척하는 것은 존재하지 않습니다.
Doval

2
일반적으로 하나의 클래스에 가능한 모든 종류의 값에 대한 변수와 해당 인스턴스가 어떤 종류의 값인지 알려주는 플래그 또는 열거 형을 포함시키고 해당하지 않는 변수 주위에서 춤을 추게됩니다 종류.
Doval

7
@Doval 인터페이스 / 추상 기본 클래스가 전체 유형을 나타내고 각 유형의 경우에 대해 서브 클래스를 가짐으로써 대수 데이터 유형을 클래스로 "표준"인코딩합니다. 패턴 일치를 처리하려면 각 경우에 대해 기능을 수행하는 메소드가 있으므로 최상위 인터페이스에 List<A>있는 메소드 인 메소드가 B Match<B>(B nil, Func<A,List<A>,B> cons)있습니다. 예를 들어, 이것은 Smalltalk가 부울에 사용하는 패턴과 정확히 같습니다. 이것은 기본적으로 스칼라가 처리하는 방식입니다. 다중 클래스가 사용된다는 것은 노출 될 필요가없는 구현 세부 사항입니다.
데릭 엘 킨스

3
@Doval : 명시 적으로 null 참조를 확인하는 것은 실제로 관용적 인 OO로 간주되지 않습니다.
JacquesB

@JacquesB 널 검사는 구현 세부 사항입니다. 연결된 목록의 클라이언트에는 일반적으로 isEmpty다음 노드에 대한 참조가 null인지 확인 하는 메소드가 있습니다.
Doval

35

함수형 프로그래밍을 배우기 전에 Pascal과 Ada에서 프로그래밍 한 후에는 차별화 된 노조를 함수형 프로그래밍과 연관시키지 않습니다.

차별 된 노조는 어떤면에서는 상속의 이중이다. 첫 번째는 고정 된 유형의 집합에 대한 작업을 쉽게 추가 할 수 있으며 (연합에있는) 상속은 고정 된 작업 집합으로 유형을 쉽게 추가 할 수 있습니다. (둘 다 쉽게 추가하는 방법을 표현식 문제 라고 합니다 . 이는 정적 유형 시스템을 사용하는 언어의 경우 특히 어려운 문제입니다.)

유형에 대한 OO의 강조와 함수에 대한 기능적 프로그래밍의 이중 강조로 인해, 기능적 프로그래밍 언어는 공용체 유형에 대한 친화력이 있으며 구문 구조를 제공하여 사용이 용이합니다.


7

OO에서 자주 사용되는 명령형 프로그래밍 기술은 종종 두 가지 패턴에 의존합니다.

  1. 성공 또는 예외 발생
  2. null"값 없음"또는 실패를 표시하기 위해 리턴하십시오 .

기능적 패러다임은 일반적으로 성공 / 실패 이유 또는 값 / 값 없음을 나타내는 복합 유형을 반환하는 것을 선호하여이 두 가지를 모두 피합니다.

차별 조합은 이러한 복합 유형에 대한 법안에 적합합니다. 예를 들어 첫 번째 인스턴스에서을 반환 true하거나 실패를 설명하는 일부 데이터 구조를 반환 할 수 있습니다 . 두 번째 경우, 값을 포함, 또는 노동 조합에서 none, nil등 두 번째 경우 많은 기능 언어가 내장 그 값 / 없음 조합을 표현하기 위해 "아마도"또는 "옵션"유형을 가지고, 그래서 일반적이다.

예를 들어 C #을 사용하여 기능적 스타일로 전환하면 이러한 복합 유형이 필요합니다. void/throw그리고 null바로 이러한 코드로 생각하지 않습니다. 그리고 차별 노동 조합 (DU)은 법안에 잘 맞습니다. 따라서 당신은 우리 중 많은 사람들처럼 자신이 원하는 것을 발견했습니다.

좋은 소식은 C #에서 DU를 모델링하는 라이브러리가 많이 있다는 것입니다 (예를 들어 내 Succinc <T> 라이브러리를 살펴보십시오).


2

합 유형은 일반적으로 주류 OO 언어에서 OO 하위 유형 지정과 유사한 유형의 문제를 해결하므로 덜 유용합니다. 그것들을 보는 한 가지 방법은 둘 다 하위 유형을 처리하지만 OO는 open즉, 하나는 부모 유형에 임의의 하위 유형을 추가 할 수 있고 합계 유형 closed은 유효한 하위 유형을 미리 결정하는 것입니다.

이제 많은 OO 언어는 상속 된 구조체, 다형성, 참조 타이핑 등과 같은 다른 개념과 하위 유형을 결합하여 일반적으로 더 유용합니다. 결과적으로 (클래스 및 생성자 등을 사용하여) 설정하는 데 더 많은 작업을하는 경향이 있으므로 일반 타이핑이 일반화 될 때까지 Results 및 Options 등에는 사용하지 않는 경향이 있습니다 .

또한 대부분의 사람들이 OO 프로그래밍을 시작할 때 배운 실제 관계 (예 : Dog isa Animal)에 중점을두면 Integer isa Result 또는 Error isa Result가 약간 외계인처럼 보입니다. 아이디어는 매우 비슷하지만.

함수형 언어가 타이핑을 열기 위해 폐쇄 형 타이핑을 선호 할 수있는 이유 중 하나는 패턴 일치를 선호하는 것입니다. 이것은 함수 다형성에 유용하지만 컴파일러가 일치하는 것이 모든 하위 유형을 포함하는지 정적으로 확인할 수 있기 때문에 닫힌 유형에서도 실제로 잘 작동합니다. 이것은 본질적인 이점이 있다고 믿지 않지만 언어를보다 일관성있게 느끼게 할 수 있습니다 (실수가 있습니다).


BTW : 스칼라는 상속을 마감했다. sealed"동일한 컴파일 단위로만 확장 할 수 있음"을 의미하므로 디자인 타임에 하위 클래스 세트를 닫을 수 있습니다.
Jörg W Mittag

-3

Swift는 차별적 인 노동 조합을 행복하게 사용합니다. 열거 형은 Swift에서 클래스, 구조체, 열거 형, 튜플 및 클로저 인 객체의 5 가지 기본 범주 중 하나입니다. Swift 옵션은 차별적 인 조합 인 열거 형이며 모든 Swift 코드에 절대적으로 필요합니다.

따라서 "차별적 노조가 기능적 프로그래밍과 관련되어있다"는 전제는 잘못되었다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.