왜 더 높은 종류가 필요합니까?


13

일부 언어는 유형 매개 변수가있는 클래스 및 함수 (예 : 임의 유형일 수있는 List<T>위치 T)를 허용합니다. 예를 들어 다음과 같은 기능을 가질 수 있습니다.

List<S> Function<S, T>(List<T> list)

그러나 일부 언어에서는이 개념을 한 단계 위로 확장하여 서명 기능을 가질 수 있습니다.

K<S> Function<K<_>, S, T>(K<T> arg)

어디 K<_>그 자체 것은 같은 유형의 List<_>그 유형 매개 변수가 있습니다. 이 "부분 유형"은 유형 생성자로 알려져 있습니다.

제 질문은 왜이 능력이 필요한가요? List<T>모든 List<T>것이 거의 동일 하기 때문에 같은 유형을 갖는 것이 합리적 이지만 모든 K<_>것은 완전히 다를 수 있습니다. 당신은 할 수 있습니다 Option<_>List<_>전혀 공통 기능이없는 것을.


7
여기에 몇 가지 좋은 답변이 있습니다 : stackoverflow.com/questions/21170493/…
itsbruce

3
@itsbruce 특히 FunctorLuis Casillas의 대답은 매우 직관적입니다. 무엇 List<T>Option<T>공통점? 당신이 나에게 하나 하나 기능을주는 경우에 T -> S나는 당신 줄 수있는 List<S>나에게 Option<S>. 그들이 공통적으로 갖는 또 다른 것은 당신 T이 둘 다 에서 가치 를 얻으려고 노력할 수 있다는 것 입니다.
Doval

@Doval : 어떻게 전자를 하시겠습니까? 후자에 관심이있는 한, 두 유형을 모두 구현하여 처리 할 수 ​​있다고 생각합니다 IReadableHolder<T>.
supercat

내가 추측하고있어 @supercat 그들은 구현해야 IMappable<K<_>, T>하는 방법과 K<S> Map(Func<T, S> f)같이 구현, IMappable<Option<_>, T>, IMappable<List<_>, T>. 따라서 사용하지 않으려면 제한 K<T> : IMappable<K<_>, T>해야합니다.
GregRos

1
캐스팅은 적절한 비유가 아닙니다. 형식 클래스 (또는 유사한 구문)로 수행되는 작업은 주어진 형식이 높은 종류의 형식을 어떻게 만족시키는 지 보여줍니다. 여기에는 일반적으로 새로운 기능을 정의하거나 기존 기능 (또는 스칼라와 같은 OO 언어 인 경우 방법)을 보여주는 것이 포함됩니다. 이 작업이 완료되면 상위 유형에서 작동하도록 정의 된 모든 기능이 해당 유형에서 작동합니다. 그러나 단순한 함수 / 메소드 시그너처 세트가 정의되어 있기 때문에 인터페이스 그 이상입니다. 나는 그것이 어떻게 작동하는지 보여주는 답을 써야 할 것 같아요.
itsbruce

답변:


5

그 누구도 그 질문에 대답하지 않았기 때문에, 나는 그것을 스스로에게 줄 것이라고 생각합니다. 나는 약간의 철학을 얻어야 할 것이다.

일반 프로그래밍은 유형 정보의 손실없이 객체 유형 값 다형성에서 발생하는 유사한 유형에 대한 추상화에 관한 것입니다. 이를 위해서는 유형이 반드시 사용할 수있는 일종의 인터페이스 (OO 용어가 아닌 일련의 작업)를 공유해야합니다.

객체 지향 언어에서 유형은 클래스 덕분에 인터페이스를 충족시킵니다. 각 클래스에는 유형의 일부로 정의 된 자체 인터페이스가 있습니다. 모든 클래스 List<T>는 동일한 인터페이스를 공유 하므로 T선택한 코드에 관계없이 작동하는 코드를 작성할 수 있습니다. 인터페이스를 적용하는 또 다른 방법은 상속 제약 조건이며, 두 가지가 다르게 보이지만 생각하면 비슷합니다.

대부분의 객체 지향 언어에서 List<>적절한 유형이 아닙니다. 메소드가 없으므로 인터페이스가 없습니다. List<T>이것들 만이 있습니다. 본질적으로,보다 기술적 인 용어로, 의미있게 추상화 할 수있는 유일한 유형은 종류가있는 유형 *입니다. 객체 지향 세계에서 더 높은 종류의 유형을 사용하려면이 제한과 일치하는 방식으로 유형 제약 조건을 표현해야합니다.

예를 들어, 주석에서 언급 한 바와 같이, 우리는 볼 수 있습니다 Option<>그리고 List<>당신은 기능이있는 경우 "맵핑이"와 같은 의미에서, 당신은 변환 할 수 있음을 Option<T>Option<S>, 또는를 List<T>List<S>. 클래스를 사용하여보다 높은 유형의 유형을 직접 추상화 할 수는 없다는 점을 기억하고 대신 인터페이스를 만듭니다.

IMappable<K<_>, T> where K<T> : IMappable<K<_>, T>

그런 다음 인터페이스를 각각 List<T>Option<T>as IMappable<List<_>, T>및 as로 구현합니다 IMappable<Option<_>, T>. 우리가 한 일은 더 높은 종류의 유형을 사용하여 실제 (높은 종류가 아닌) 유형 Option<T>과에 제한을 두는 것 List<T>입니다. 물론 Scala는 특성, 유형 변수 및 암시 적 매개 변수와 같은 기능을 통해보다 표현력을 향상시킬 수 있습니다.

다른 언어에서는 더 높은 종류의 유형을 직접 추상화 할 수 있습니다. 유형 시스템의 최고 권한 중 하나 인 Haskell에서는 유형이 더 높더라도 모든 유형에 대한 유형 클래스를 문구화할 수 있습니다. 예를 들어

class Mappable mp where
    map :: mp a -> mp b

이것은 mp하나의 유형 매개 변수를 취하는 (지정되지 않은) 유형에 직접 배치되는 제약 조건 map이며 mp<a>로 변환하는 함수와 관련되어야 합니다 mp<b>. 그런 다음 Mappable상속 제한을 적용 할 수있는 객체 지향 언어와 같이 더 높은 종류의 유형을 제한하는 함수를 작성할 수 있습니다 . 글쎄요.

요약하면, 상위 유형의 유형을 사용하는 능력은 유형을 제한하거나 유형 제약 조건의 일부로 사용하는 능력에 달려 있습니다.


너무 바빠서 직장을 바꾸었지만 마침내 내 자신의 답변을 쓸 시간이 있습니다. 그래도 제약 조건이라는 생각에 정신이 산만하다고 생각합니다. 더 높은 종류의 유형의 중요한 측면 중 하나 는 논리적으로 자격을 갖춘 것으로 보여 질 수있는 모든 유형에 적용 할 수있는 기능 / 동작을 정의 할 수 있다는 것입니다. 기존 유형에 제약 조건을 부과하는 것과는 달리 유형 클래스 (고급 유형의 하나의 응용 프로그램)는 동작을 추가합니다.
itsbruce

시맨틱의 문제라고 생각합니다. 타입 클래스는 타입의 클래스를 정의합니다. 와 같은 함수를 정의 할 때 class 유형의 멤버가되도록 (Mappable mp) => mp a -> mp b제약 조건을 설정 mp했습니다 Mappable. Option의 인스턴스 와 같은 유형을 선언하면 Mappable해당 유형에 동작이 추가됩니다. 유형을 제한하지 않고 해당 동작을 로컬에서 사용할 수 있지만 일반적인 기능을 정의하는 것과 다르지 않습니다.
GregRos

또한 유형 클래스가 상위 유형과 직접 관련이없는 것이 확실합니다. 스칼라는 더 높은 유형의 유형을 가지고 있지만 유형 클래스는 없으므로 유형 클래스를 *사용할 수 없게 만들지 않고 유형이있는 유형으로 제한 할 수 있습니다. 그러나 종류가 높은 유형으로 작업 할 때 유형 클래스가 매우 강력하다는 것은 분명합니다.
GregRos

스칼라는 유형 클래스가 있습니다. 그것들은 암시 적으로 구현됩니다. 암시 적은 Haskell 유형 클래스 인스턴스에 해당합니다. 전용 구문이 없기 때문에 Haskell보다 더 취약한 구현입니다. 그러나 그것은 항상 스칼라 암시 적의 주요 목적 중 하나였으며 그들은 일을합니다.
itsbruce
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.