상위 매개 변수 다형성이 유용합니까?


16

나는 모든 사람들이 일반적인 형식의 방법에 익숙하다고 확신합니다.

T DoSomething<T>(T item)

이 기능은 PP (parametrically polymorphic), 특히 순위 1 PP 라고도 합니다.

이 방법이 다음 형식의 함수 객체를 사용하여 표현 될 수 있다고 가정 해 봅시다.

<T> : T -> T

즉, <T>하나의 유형 매개 변수를 사용하고 유형의 매개 T -> T변수를 하나 사용 T하여 동일한 유형의 값을 리턴 함을 의미합니다 .

다음은 순위 -2 PP 함수입니다.

(<T> : T -> T) -> int 

이 함수는 형식 매개 변수 자체를 사용하지 않지만 형식 매개 변수를 사용하는 기능을 수행합니다. 이 과정을 반복적으로 계속하면 중첩이 더 깊고 깊어지고 PP의 등급이 높아집니다.

이 기능은 프로그래밍 언어에서 거의 사용되지 않습니다. Haskell조차도 기본적으로 허용하지 않습니다.

유용합니까? 달리 설명하기 어려운 행동을 묘사 할 수 있습니까?

또한 무언가가 비현실적 이라는 것은 무엇을 의미 합니까? (이 맥락에서)


1
흥미롭게도 TypeScript는 전체 순위 n PP를 지원하는 주류 언어 중 하나입니다. 예를 들어, 다음은 유효한 TypeScript 코드입니다.let sdff = (g : (f : <T> (e : T) => void) => void) => {}
GregRos

답변:


11

당신이 할 때 일반적으로, 당신은 더 높은 순위 다형성을 사용하여 수신자가 오히려보다는 형식 매개 변수의 값을 선택 할 수 있도록 발신자 . 예를 들면 다음과 같습니다.

f :: (forall a. Show a => a -> Int) -> (Int, Int)
f g = (g "one", g 2)

g내가 전달하는 모든 함수 는 어떤 유형의 값에서 f나에게 Int값 을 줄 수 있어야합니다. 이 유형에 대해 아는 유일한 것은 g해당 유형의 인스턴스가 있다는 것입니다 Show. 따라서 이들은 정결합니다.

f (length . show)
f (const 42)

그러나 이것들은 아닙니다 :

f length
f succ

하나 특히 유용한 응용 프로그램의 범위 지정 사용에 유형 의 범위 지정 시행하는 . 미래 또는 콜백과 같은 Action<T>유형의 결과를 생성하기 위해 실행할 수있는 조치를 나타내는 유형의 오브젝트가 있다고 가정하십시오 T.

T runAction<T>(Action<T>)

runAction :: forall a. Action a -> a

이제 객체 Action를 할당 할 수있는 Resource<T>객체 가 있다고 가정 해 봅시다 .

Action<Resource<T>> newResource<T>(T)

newResource :: forall a. a -> Action (Resource a)

이러한 리소스는 리소스 가 만들어진 곳 에서만 사용되고 Action다른 작업이나 동일한 작업의 다른 실행간에 공유되지 않도록 결정하여 작업이 결정적이고 반복 가능하도록해야합니다.

및 유형에 매개 변수 S를 추가하여 순위가 높은 유형을 사용하여이를 달성 할 수 있습니다 . 이는 완전히 추상적 입니다. 이제 우리의 서명은 다음과 같습니다.ResourceActionAction

T run<T>(<S> Action<S, T>)
Action<S, Resource<S, T>> newResource<T>(T)

runAction :: forall a. (forall s. Action s a) -> a
newResource :: forall s a. a -> Action s (Resource s a)

우리가 줄 때 이제 runActionAction<S, T>, 우리는 "범위"매개 변수가 있기 때문에 안심하는 S완벽 다형성, 그것은의 몸을 벗어날 수 없다 runAction- 그래서 사용하는 형태의 값 S등이 Resource<S, int>마찬가지로 벗어날 수 있습니다!

(하스켈에서는,이은으로 알려져 ST모나드, runAction호출 runST, Resource호출 STRefnewResource호출 newSTRef).


ST모나드는 매우 흥미로운 예이다. 상위 순위 다형성이 유용한 경우에 대한 몇 가지 예를 더 제시 할 수 있습니까?
GregRos

@GregRos : 그것은 또한 존재하기 편리합니다. 에서는 Haxl , 우리는 존재했다 같은 data Fetch d = forall a. Fetch (d a) (MVar a)데이터 소스에 대한 요청의 쌍이며, d그 결과를 저장할 슬롯. 결과 및 슬롯에는 일치하는 유형이 있어야하지만 해당 유형은 숨겨져 있으므로 동일한 데이터 소스에 대한 이기종 요청 목록을 가질 수 있습니다. 이제 상위 다형성을 사용하여 하나를 가져 오는 함수가 있으면 모든 요청을 가져 오는 함수를 작성할 수 있습니다 fetch :: (forall a. d a -> IO a) -> [Fetch d] -> IO ().
Jon Purdy

8

높은 순위 다형성은 매우 유용합니다. System F (숙련 된 FP 언어의 핵심 언어)에서 이것은 System F가 프로그래밍하는 방식 인 "유형 교회 인코딩"을 인정하는 데 필수적입니다. 이것들이 없으면 시스템 F는 완전히 쓸모가 없습니다.

시스템 F에서는 숫자를 다음과 같이 정의합니다.

Nat = forall c. (c -> c) -> c -> c

추가 유형이 있습니다

plus : Nat -> Nat -> Nat
plus l r = Λ t. λ (s : t -> t). λ (z : t). l s (r s z)

더 높은 순위 유형입니다 ( forall c.화살표 안에 나타남).

이것은 다른 장소에서도 나타납니다. 예를 들어, 계산이 올바른 연속 전달 스타일 (Google "codensity haskell")임을 나타내려면 다음과 같이하면됩니다.

type CPSed A = forall c. (A -> c) -> c

System F에서 무인 유형에 대해 이야기하더라도 높은 순위 다형성이 필요합니다.

type Void = forall a. a 

이것의 길고 짧은, 순수한 타입 시스템 (System F, CoC)에서 함수를 작성하는 것은 흥미로운 데이터를 다루기 위해서는 더 높은 순위 다형성이 필요합니다.

특히 시스템 F에서 이러한 인코딩은 "고급 적"이어야합니다. 이것은 절대적으로 모든 유형을forall a. 정량화 한다는 것을 의미합니다 . 여기에는 우리가 정의하는 바로 그 유형이 포함됩니다. 에서 그 사실에 대해 참을 수 다시! ML과 같은 언어에서는 그렇지 않습니다. 유형 변수는 한정자가 없는 유형 집합 (단일 유형 이라고 함)에 대해서만 수량화하기 때문에 "예측 적" 이라고합니다. 우리의 정의 가 필요 impredicativity 우리는 인스턴스화 잘 때문에 같은 에서 할 수 !forall a. aaforall a. apluscl : NatNat

마지막으로, 임의 재귀 유형 (시스템 F와 달리)에서도 비현실 성과 높은 순위의 다형성을 모두 원하는 마지막 이유에 대해 언급하고 싶습니다. Haskell에는 "상태 스레드 모나드"라는 효과에 대한 모나드가 있습니다. 아이디어는 상태 스레드 모나드를 사용하여 사물을 변경할 수 있지만 결과가 변경 가능한 것에 의존하지 않도록 탈출해야합니다. 이것은 ST 계산이 상당히 순수하다는 것을 의미합니다. 이 요구 사항을 적용하기 위해 더 높은 순위 다형성을 사용합니다.

runST :: forall a. (forall s. ST s a) -> a

여기서 a우리가 소개하는 범위를 벗어나는 것을 보장함으로써 s, 우리 a는 의존하지 않는 잘 구성된 유형 을 나타냅니다 s. 우리는 s특정 상태 스레드에서 모든 변경 가능한 것들을 매개 변수화 하기 위해 사용 합니다. 그래서 우리는 그것이 a변경 가능한 것들과 독립적이므로 아무것도 그 ST계산 의 범위를 벗어나지 않습니다 ! 형식이 잘못된 프로그램을 배제하는 훌륭한 예입니다.

그건 그렇고, 당신이 유형 이론에 대해 배우고 싶다면 좋은 책에 투자하는 것이 좋습니다. 이 내용을 조금씩 배우기가 어렵습니다. 나는 PL 이론에 대한 Pierce 또는 Harper의 책 중 하나를 제안 할 것입니다 (및 유형 이론의 일부 요소). "유형 및 프로그래밍 언어의 고급 주제"책에도 많은 유형 이론이 포함되어 있습니다. 마지막으로 "Martin Lof의 유형 이론에서 프로그래밍"은 Martin Lof가 설명한 강렬한 유형 이론에 대한 훌륭한 설명입니다.


추천 해 주셔서 감사합니다. 내가 찾아 볼게 이 주제는 정말 흥미롭고, 더 많은 프로그래밍 언어에서 더 고급 유형 시스템 개념이 채택되기를 바랍니다. 그들은 당신에게 훨씬 더 표현력을 제공합니다.
GregRos
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.