ST 모나드는 어떻게 작동합니까?
나는 ST 모나드가 IO의 남동생과 비슷하다는 것을 알고 있으며, 이는 다시 RealWorld
마법 이 추가 된 상태 모나드입니다 . 나는 상태를 그릴 수 나는 RealWorld 어떻게 든 IO에 투입되는 사진 수 있지만, 때마다 나는의 유형 서명 쓰기 목표 명세서가 모나드 혼란 날을.ST
s
예를 들어 ST s (STArray s a b)
. s
거기에서 어떻게 작동합니까? 상태 모나드의 상태처럼 참조 할 수없는 상태 (으로 인해 forall
) 없이 계산간에 인위적인 데이터 종속성을 구축하는 데 사용 됩니까?
나는 단지 아이디어를 던지고 있고 그것을 설명해 줄 수있는 나보다 더 많은 지식을 가진 사람에게 정말로 감사 할 것입니다.
는 s
내부 객체 유지 ST
의 외부로 누출 모나드를 ST
모나드.
-- This is an error... but let's pretend for a moment...
let a = runST $ newSTRef (15 :: Int)
b = runST $ writeSTRef a 20
c = runST $ readSTRef a
in b `seq` c
좋아요, 이것은 유형 오류입니다 (좋은 일입니다! 우리는 STRef
원래 계산 밖으로 유출 하고 싶지 않습니다 !). 추가로 인해 유형 오류 s
입니다. runST
서명이 있음을 기억하십시오 .
runST :: (forall s . ST s a) -> a
즉, s
실행중인 계산에 대한 제약이 없어야합니다. 따라서 평가하려고 할 때 a
:
a = runST (newSTRef (15 :: Int) :: forall s. ST s (STRef s Int))
결과는 유형을 갖게 STRef s Int
되는데 이는이 in s
외부에서 "이스케이프" 되었기 때문에 잘못된 것 forall
입니다 runST
. 유형 변수는 항상 내부에 나타나야 forall
하며 Haskell은 forall
모든 곳에서 암시 적 수량 자를 허용 합니다. 의 반환 유형을 의미있게 파악할 수있는 규칙은 없습니다 a
.
다음과 같은 또 다른 예 forall
: 를 이스케이프 할 수없는 이유를 명확하게 보여주기 위해 forall
다음은 더 간단한 예입니다.
f :: (forall a. [a] -> b) -> Bool -> b
f g flag =
if flag
then g "abcd"
else g [1,2]
> :t f length
f length :: Bool -> Int
> :t f id
-- error --
물론 부울이 참인지 거짓인지 에 따라 목록 또는 f id
목록을 반환하므로 오류입니다. .NET의 예제처럼 단순히 잘못되었습니다 .Char
Int
ST
반면에s
타입 매개 변수가 없다면 코드가 꽤 가짜 임에도 불구하고 모든 것이 제대로 타입 검사를 할 것입니다.
ST가 실제로 작동하는 방식 : 구현 측면에서 ST
모나드는 실제로 모나드와 동일 IO
하지만 인터페이스가 약간 다릅니다. ST
모나드 를 사용할 때 실제로 얻 unsafePerformIO
거나 그에 상응하는 것, 뒤에서. 이 작업을 안전하게 수행 할 수있는 이유는 모든 ST
관련 함수, 특히 forall
.
이것은 s
타입 시스템이 안전하지 않은 일을하는 것을 막는 해킹 일뿐입니다. 런타임에 아무것도 "하지"않습니다. 유형 검사기가 모호한 작업을 수행하는 프로그램을 거부하게 만듭니다. (소위 팬텀 타입으로 타입 체커의 헤드에만 존재하며 런타임에 영향을주지 않습니다.)
참고 URL : https://stackoverflow.com/questions/12468622/how-does-the-st-monad-work
'Program Tip' 카테고리의 다른 글
vim은 기본적으로 시스템 클립 보드를 사용할 수 있습니까? (0) | 2020.11.08 |
---|---|
pid가 다른 여러 Java 프로세스를 보여주는 Htop (0) | 2020.11.08 |
ReferenceError를 제공하는 Javascript require () 함수 : require가 정의되지 않았습니다. (0) | 2020.11.08 |
로그에서 잘리는 스택 추적을 어떻게 중지합니까? (0) | 2020.11.08 |
Java의 System.exit ()는 try / catch / finally 블록과 어떻게 작동합니까? (0) | 2020.11.08 |