심지어 pipes-parse
이상이면 pipes-group
을보고 싶을 것입니다. 특히,의 함수를 살펴 보자
-- this type is slightly specialized
chunksOf
:: Monad m =>
Int ->
Lens' (Producer a m x) (FreeT (Producer a m) m x)
Lens'
비트는 아마도 무서운하지만 신속하게 제거 할 수있다 : 우리가 [0] 그래서
import Control.Lens (view)
chunkIt :: Monad m => Int -> Producer a m x -> FreeT (Producer a m) m x
chunkIt n = view (chunksOf n)
지금 우리가 가지고 Producer a m x
FreeT (Producer a m) m x
에 변환 할 수 있다고 그 FreeT
비트로 무엇을 해야할지 알아냅니다. 특히, 우리는 free
패키지로 파고 기능 iterT
iterT
:: (Functor f, Monad m) =>
(f (m a) -> m a) ->
(FreeT f m a -> m a)
이 기능, iterT
을 당겨의 우리 한 번에 FreeT
하나 "단계"를 "소비"수 있도록 할 것입니다. 이 문제를 이해하려면, 우리가 처음 특히 Producer a m
runChunk :: Monad m =>
(Producer a m (m x) -> m x) ->
(FreeT (Producer a m) m x -> m x)
runChunk = iterT
와 f
을 대체 할 iterT
의 유형을 전문으로합니다, runChunk
가 할 수있는 "실행"는 Producer
가득 FreeT
그래서 우리가 어떻게 Producer a m (m x)
를 변환하는 방법을 이야기로이야 m
-action으로 이동하십시오. 이은 더 익숙해 보일 수 있습니다. runChunk
의 첫 번째 인수를 정의 할 때 Producer
을 실행하기 만하면됩니다.이 경우에는 선택된 요소 수를 초과하지 않습니다.
그러나 유효한 반환 값은 무엇입니까 m x
? '계속'입니다. 현재 다음에 오는 모든 청크는 입니다. 그래서, 예를 들어, 우리가 Producer
Char
의의를 가지고 가정하자 우리는 3 자
후 인쇄 LINEBREAK 싶습니다 main :: IO()
main = flip runChunk (chunkIt 3 input) $ \p -> _
이 시점에서 _
구멍이 맥락에서의 p
와 IO()
을 입력있다 p :: Producer Char IO (IO())
을 입력하십시오. for
으로이 파이프를 소비하고 리턴 유형을 수집하고 (다시 계속), 개행을 내 보낸 다음 그 연속을 계속 실행할 수 있습니다.모든 조각이 어떻게 들어 맞는지 볼 일단
input :: Monad m => Producer Char m()
input = each "abcdefghijklmnopqrstuvwxyz"
main :: IO()
main = flip runChunk (chunkIt 3 input) $ \p -> do
cont <- runEffect $ for p (lift . putChar)
putChar '\n'
cont
내가 박람회의 조금 한 반면, 명확하게하기 위해
λ> main
abc
def
ghi
jkl
mno
pqr
stu
vwx
yz
을 원하는대로이 정확히 동작이 매우 간단 코드입니다. 전체 목록은 다음과 같습니다. input :: Monad m => Producer Char m()
input = each "abcdefghijklmnopqrstuvwxyz"
main :: IO()
main = flip iterT (input ^. chunksOf 3) $ \p -> do
cont <- runEffect $ for p $ \c -> do
lift (putChar c)
putChar '\n'
cont
[0] 또한 약간 이상이지만 지금은 충분합니다.