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
'IT이야기' 카테고리의 다른 글
128비트 정수 모듈로 64비트 정수를 계산하는 가장 빠른 방법 (0) | 2021.09.23 |
---|---|
템플릿 구조/클래스를 친구로 선언하는 방법 (0) | 2021.09.23 |
바이트 대신 Enum Int32의 기본 유형을 만들어야 하는 이유 (0) | 2021.09.23 |
두 개의 Python 모듈에는 서로의 내용이 필요한 경우 (0) | 2021.09.23 |
로컬 maven 저장소 생성 (0) | 2021.09.22 |