글쎄, 이것은 재미가 조금 놀랍습니다.
pullFrom
가 도입되어 소비자가 프로세스가 형성 될 때 "책임이 있음"- 소비자가 열려있는 동안 (입력을 기다리는) 프로세스가 존재합니다.
connect
은 생산자 또는 고객이 열려있는 한 실행되며 두 프로세스가 모두 완료되면 프로세스가 종료됩니다. 과정 만 consumer
에 의존하기 때문에이 필요하지 않습니다 pullFrom
- 생성 된 프로세스가 소비자와 생산자 모두에 따라 달라집니다로 이것을 달성하기
는
connect
는
Parallel
클래스 제약 조건이있다.
"재미"가 놀라는 순간입니다. 잠시 혼란스러워합니다. Eff
은 Parallel
이 아니므로 코드가 어떻게 작동합니까? 이 main
이 유형을 추론하는 것 때문입니다 : 프로그램이 실행될 때 JS에서, main
이 사전은 Parallel
제한 조건에 대해 전달 될 것으로 예상되기 때문에
main :: forall t. (Parallel t (Eff (console :: CONSOLE))) => Eff (console :: CONSOLE) Unit
그래서 아무것도, 발생하지, 다음 Eff
을 평가한다. main에 대한 생성 된 호출은 Main.main();
이므로 Main.main(impossibleParallelDictionary)();
일 필요가 있으므로 실제로는 Eff
을 평가하지 않습니다. 당신의 main
이 유형을 추가
시도 :
main :: Eff (console :: CONSOLE) Unit
그리고 당신이 더 이상 확인 입력하지 않는 것을 볼 수 있습니다.
당신은 생각이에 대한
Aff
을 사용할 수 있습니다
및 Aff
와 connect
및 pullFrom
의 차이는이 예를 들어, 구별 : 우리는 약간의 예제를 수정하는 경우, 우리는 그 차이의 그림을 볼 수 있습니다
import Prelude
import Control.Coroutine (Consumer, Producer, await, connect, emit, runProcess)
import Control.Monad.Aff (Aff, launchAff)
import Control.Monad.Aff.Console (CONSOLE, log)
import Control.Monad.Eff (Eff)
import Control.Monad.Eff.Exception (EXCEPTION)
import Control.Monad.Rec.Class (forever)
import Control.Monad.Trans.Class (lift)
consumer :: forall e a. (Show a) => Consumer a (Aff (console :: CONSOLE | e)) Unit
consumer = forever do
s <- await
lift (log $ show s)
numberProducer :: forall m. (Monad m) => Producer Int m Unit
numberProducer = go 0
where
go i = do emit i
go (i + 1)
main :: Eff (err :: EXCEPTION, console :: CONSOLE) Unit
main = void $ launchAff $ runProcess (connect numberProducer consumer)
:
import Prelude
import Control.Coroutine (Consumer, Producer, await, emit, connect, runProcess)
import Control.Monad.Aff (Aff, launchAff, later')
import Control.Monad.Aff.Console (CONSOLE, log)
import Control.Monad.Eff (Eff)
import Control.Monad.Eff.Exception (EXCEPTION)
import Control.Monad.Trans.Class (lift)
consumer :: forall e a. (Show a) => Consumer a (Aff (console :: CONSOLE | e)) Unit
consumer = do
s <- await
lift (log $ show s)
numberProducer :: forall eff. Producer Int (Aff eff) Unit
numberProducer = do
emit 0
lift $ later' 10000 $ pure unit
main :: Eff (err :: EXCEPTION, console :: CONSOLE) Unit
main = void $ launchAff $ runProcess (connect numberProducer consumer)
이렇게하면 프로그램이 0을 인쇄하고 10 초 기다렸다가 종료합니다. consumer `pullFrom` numberProducer
에 대해 connect numberProducer consumer
을 전환하면 프로그램이 0을 인쇄하고 즉시 종료됩니다.
감사합니다. gb, 의미가 있습니다! "생산자 또는 소비자가 열려있는 한 연결 실행에 대한 참고 사항을 분명히 할 수 있으며 프로세스가 완료 될 때만 프로세스가 종료됩니다." 그 말은 "어느 것이 든 완료되면 끝나야합니까?" 하나의 값만 기다리는 소비자를 만듭니다 (즉, 위의 소비자 함수에서 '영원히'를 제거합니다), numberProducer는 여전히 '열리 며'프로세스를 열어 두는 것처럼 보입니다. – Albtzrly
'pullFrom'과'connect'의 차이점을 관찰 할 수있는 답을 보여주는 또 다른 예제를 편집했습니다. 나는 "open"에 대한 나의 설명이 그것을 표현하는 최선의 방법이 아닐 수도 있다고 생각한다 - 내 설명에서 "emit step"을위한 기능이 아직 완성되지 않았다면 생산자는 "open"이다. 따라서 무한한 생산자와 한정된 소비자가 있더라도 소비자는 '연결'을 통해 (또는 그 반대로) 프로세스가 종료됩니다. –
추가 예를 보내 주셔서 감사합니다. – Albtzrly