IT이야기

runST 및 함수 구성

cyworld 2021. 9. 23. 22:42
반응형

runST 및 함수 구성


이 유형 검사가 수행되는 이유는 다음과 같습니다.

runST $ return $ True

다음은 그렇지 않습니다.

runST . return $ True

GHCI는 다음과 같이 불평합니다.

Couldn't match expected type `forall s. ST s c0'
            with actual type `m0 a0'
Expected type: a0 -> forall s. ST s c0
  Actual type: a0 -> m0 a0
In the second argument of `(.)', namely `return'
In the expression: runST . return

짧은 대답은 유형 추론이 항상 상위 유형에서 작동하는 것은 아니라는 것입니다. 이 경우 유형을 유추할 수 (.)없지만 명시적 유형 주석을 추가하는지 유형을 확인합니다.

> :m + Control.Monad.ST
> :set -XRankNTypes
> :t (((.) :: ((forall s0. ST s0 a) -> a) -> (a -> forall s1. ST s1 a) -> a -> a) runST return) $ True
(((.) :: ((forall s0. ST s0 a) -> a) -> (a -> forall s1. ST s1 a) -> a -> a) runST return) $ True :: Bool

($)우리 자신의 버전으로 교체하면 첫 번째 예제에서도 동일한 문제가 발생합니다 .

> let app f x = f x
> :t runST `app` (return `app` True)
<interactive>:1:14:
    Couldn't match expected type `forall s. ST s t0'
                with actual type `m0 t10'
    Expected type: t10 -> forall s. ST s t0
      Actual type: t10 -> m0 t10
    In the first argument of `app', namely `return'
    In the second argument of `app', namely `(return `app` True)'

다시 말하지만, 이것은 유형 주석을 추가하여 해결할 수 있습니다.

> :t (app :: ((forall s0. ST s0 a) -> a) -> (forall s1. ST s1 a) -> a) runST (return `app` True)
(app :: ((forall s0. ST s0 a) -> a) -> (forall s1. ST s1 a) -> a) runST (return `app` True) :: Bool

여기서 일어나는 일은 GHC 7에 표준 ($)연산자 에만 적용되는 특별한 타이핑 규칙이 있다는 것입니다 . Simon Peyton-Jones는 GHC 사용자 메일링 리스트의 답장에서 이 동작을 설명 합니다 .

이것은 암시적 유형을 다룰 수 있는 유형 추론에 대한 동기를 부여하는 예입니다. 다음 유형을 고려하십시오 ($).

($) :: forall p q. (p -> q) -> p -> q

이 예에서 우리는 인스턴스를 필요 p(forall s. ST s a)하고, 그 무엇 impredicative 다형성 수단 : 다형성 유형의 형태 변수를 인스턴스화.

슬프게도, 나는 도움 없이 [이것]을 typecheck할 수 있는 합리적인 복잡성의 시스템이 없다는 것을 알고 있습니다. 복잡한 시스템이 많이 있으며 적어도 두 가지에 대한 논문의 공동 저자이지만 GHC에 살기에는 모두 너무 복잡합니다. 우리는 boxy 유형을 구현했지만 새로운 유형 검사기를 구현할 때 제거했습니다. 아무도 그것을 이해하지 못했습니다.

그런데 사람들이 자주 쓰는

runST $ do ... 

GHC 7에서는 ($). (f $ x)명백한 타이핑 규칙이 있는 새로운 구문 형식으로 생각하면 됩니다.

에 대한 그러한 규칙이 없기 때문에 두 번째 예는 실패합니다 (.).


The runST $ do { ... } pattern is so common, and the fact that it normally wouldn't type-check is so annoying, that GHC included some ST-specific type-checking hacks to make it work. Those hacks are probably firing here for the ($) version, but not the (.) version.


The messages are a bit confusing the point (or so I feel). Let me rewrite your code:

runST (return True)   -- return True is ST s Bool
(runST . return) True  -- cannot work

Another way to put this is that the monomorphic m0 a0 (the result of return, if it would get an a0) cannot be unified with (forall s.ST s a).

ReferenceURL : https://stackoverflow.com/questions/9468963/runst-and-function-composition

반응형