2012-12-17 7 views
19

두 아이디어 사이에는 강력한 연관성이있는 것으로 보입니다. 필자의 추측에 따르면 Iteratees를 사용하여 임의의 그래프를 표현할 수있는 방법이 있다면 FRP를 Iteratees 측면에서 구현할 수 있습니다. 하지만 afaik는 체인과 같은 구조 만 지원합니다.Iteratees와 FRP 사이의 연결은 무엇입니까?

누군가가이 문제에 대해 의견을 개진 할 수 있습니까?

답변

13

그 반대의 경우입니다. AFRP와 스트림 처리 사이에는 강력한 연결이 있습니다. 사실 AFRP 스트림 처리의 한 형태이고, 당신은 파이프와 매우 비슷한 구현하는 관용구를 사용할 수 있습니다

Netwire에서 발견 와이어 카테고리의 확장이다
data Pipe m a b = 
    Pipe { 
     cleanup :: m(), 
     feed :: [a] -> m (Maybe [b], Pipe m a b) 
    } 

. 다음 입력 청크를 받고 생성이 중지되면 Nothing을 반환합니다.

fmap (B.map toUpper) . readFile 
: 당신은 그냥 fmap 함수을 사용할 수 있도록 스트림 요소에 간단한 기능을 적용,

readFile :: (MonadIO m) => FilePath -> Pipe m a ByteString 

파이프 실용적 펑의 가족 :이 파일 리더를 사용하면 다음과 같은 유형을 가질 것

귀하의 편의를 위해 그것은 또한 전문가의 가족입니다.

가장 흥미로운 기능은 대체 펑터 제품군입니다. 이를 통해 스트림을 주변으로 라우팅하고 여러 스트림 프로세서가 포기하기 전에 "시도"할 수 있습니다. 이것은 최적화 목적으로 일부 정적 정보를 사용할 수있는 본격적인 파싱 라이브러리로 확장 될 수 있습니다.

+0

아, 나는 비슷한 것을 게시하려했으나 AFRP 라이브러리를 실제로 작성한 사람의 전문 기술을 연기 할 것입니다. :] –

+0

(A) FRP를 사용하면 비순환 그래프 구조로 제한되지 않는 것 같습니다. 사실입니까? – fho

+3

AFRP의 어떤 측면이 라이브러리 도관/파이프를 보유하고있는 용어 나 최근의 흐름으로 구현 될 수 없다면 당신의 대답으로는 분명하지 않습니다. – Davorak

13

스트림 프로세서를 사용하여 제한된 형태의 FRP를 구현할 수 있습니다. 예를 들어, pipes 라이브러리를 사용하여, 당신은 이벤트의 소스 정의 할 수 있습니다 :

mouseCoordinates :: (Proxy p) =>() -> Producer p MouseCoord IO r 

을 ... 당신은 유사 마우스 좌표를 소요하고 캔버스에 커서를 업데이트하는 그래픽 처리기 정의 할 수 있습니다 :

coordHandler :: (Proxy p) =>() -> Consumer p MouseCoord IO r 

>>> runProxy $ mouseCoordinates >-> coordHandler 

을 그리고 그것은 당신이 기대 다만 방법을 실행하는 것입니다 :

그럼 당신은 조성물을 이용하여 핸들러에 마우스 이벤트를 연결합니다.

당신이 말했듯이 이것은 단일 스테이지 체인에 적합하지만 임의의 토폴로지는 어떻습니까? 글쎄, 타입의 pipes이 모나드 변압기이므로 Proxy 타입이 모아서 프록시 모나드 트랜스포머를 중첩하여 임의의 토폴로지를 모델링 할 수 있습니다. 예를 들어 두 입력 스트림을 압축하는 방법은 다음과 같습니다.

zipD 
:: (Monad m, Proxy p1, Proxy p2, Proxy p3) 
=>() -> Consumer p1 a (Consumer p2 b (Producer p3 (a, b) m)) r 
zipD() = runIdentityP $ hoist (runIdentityP . hoist runIdentityP) $ forever $ do 
    a <- request()    -- Request from the outer Consumer 
    b <- lift $ request()  -- Request from the inner consumer 
    lift $ lift $ respond (a, b) -- Respond to the Producer 

이 함수는 카레 함수처럼 작동합니다. 부분적으로 각 입력에 순차적으로 적용하고 완전히 적용되면이를 실행할 수 있습니다.

>>> p3 
(1, 4) 
(2, 5) 
(3, 6) 

이 트릭은 어떤 토폴로지에 일반화 :

-- 1st application 
p1 = runProxyK $ zipD <-< fromListS [1..] 

-- 2nd application 
p2 = runProxyK $ p2  <-< fromListS [4..6] 

-- 3rd application 
p3 = runProxy $ printD <-< p3 

그것은 당신이 기대 다만 방법을 실행합니다.자세한 내용은 Control.Proxy.Tutorial에서 "지점, zip 및 병합"섹션을 참조하십시오. 특히, 스트림을 두 개의 출력으로 나눌 수 있도록 예제로 사용하는 조합 자 fork을 확인해야합니다.

+0

나는 이것이 모든 제정신의 iteratee 라이브러리에 사실임을 확신한다. 올렉은 얼마 전에 그것을 사용했습니다. 왜 아무도 그것이 가능하다는 것을 기억하지 못하는 이유를 모르겠습니다. 이 기술은 매우 유용합니다. –

+0

@JohnL 그래서 설교해야합니다! 모든 사람들이 올렉이 한 일을 잘 압니다. –

+0

Oleg이 종종 이해하지 못한 것을 아는 사람들조차도 그것을 이해하지 못합니다. 슬프게도 나는 적어도이 그룹에 자주있다. –