重构管道界面 [英] Refactor pipes interface
问题描述
我正在使用管道库(4.1.4)编制一个编码器模型。
我有一个工作函数
encode ::(Monad m )=> Int - > - - 每位代码数量
生产者Word32 m r - > - 代码源
生产者Word32 m r - > - 数据源
生产者Word32 mr - 结果流
编码n cp dp = P.zip与xor cp(dp> - >(upsample n))
$ c $ encode ::(Monad m)=> Int - >
Producer Word32 m r - >
Pipe Word32 m
我认为它的用法更清晰;它编码流过管道的数据。我还没有第一个想法如何实现这一点。
编辑
upsample :: Int - >管Word32 Word32 mr
解决方案我想你需要这个:
encode n cp = upsample n> - > f cp其中
f c = do
r < - lift $ next c
case r of
Left r - > return r - 在这里使用f cp,如果你的意思是Viginere
Right(x,c') - >
y< - 等待
收益$ x`xor` y
f c'
这里 encode
将等待来自 cp
的值:如果它变得可用,它会记住值并从 upsample
管道获得一个值, yield
编码值,并循环到编码删除 x后, cp
剩余的 Producer
。这样它将并行迭代 cp
和数据,就像 zipWith
。
我不知道 upsample
是什么,所以我定义为一个否定管:
upsample :: Monad m => Int - > Pipe Int Int mr
upsample n = do
x <-await
yield $ -x
upsample n
encode n cp =(upsample n) > - > f cp其中
f cp = do
r < - lift $ next cp
case r of
Left r - >返回r
Right(x,cp) - >做
y< - 等待
收益$ x * y - 我懒得导入位
f cp
Prelude Pipes> runEffect $ mapM_ yield [0 ..]> - >
编码10(mapM_ yield [1..10])> - >
sequence_(repeat $ do {x < - await; lift $ print x})
0
-2 - 记住,[0 ..]被upsample取反,然后乘以[1..10]
-6
-12
-20
-30
-42
-56
-72
-90 - `cp`中只有10个项目可用,因此只打印10个项目
I'm putting together a model of an encoder using the pipes library (4.1.4).
I have a working function
encode :: (Monad m) => Int -> - -- number of codes per bit
Producer Word32 m r -> -- code source
Producer Word32 m r -> -- data source
Producer Word32 m r -- resulting stream
encode n cp dp = P.zipWith xor cp (dp >-> (upsample n))
And I'd like to refactor it as
encode :: (Monad m) => Int ->
Producer Word32 m r ->
Pipe Word32 m r
I think its usage is clearer; it encodes data flowing through the pipe. I haven't the first idea how to achieve this.
EDIT
upsample :: Int -> Pipe Word32 Word32 m r
解决方案 I think you need this:
encode n cp = upsample n >-> f cp where
f c = do
r <- lift $ next c
case r of
Left r -> return r -- use f cp here, if you really meant Viginere
Right (x, c') -> do
y <- await
yield $ x `xor` y
f c'
Here encode
will await for the value from cp
: if it becomes available, it will remember the value and get one value from upsample
pipe, yield
the encoded value, and loop to encode
the remainder of the Producer
left from cp
after removing x
. That way it will iterate the cp
and data in parallel, just like zipWith
.
I don't know what upsample
is like, so I defined is as a negating pipe:
upsample :: Monad m => Int -> Pipe Int Int m r
upsample n = do
x<-await
yield $ -x
upsample n
encode n cp = (upsample n) >-> f cp where
f cp = do
r <- lift $ next cp
case r of
Left r -> return r
Right (x,cp) -> do
y <- await
yield $ x*y -- I was lazy to import Bits
f cp
Prelude Pipes> runEffect $ mapM_ yield [0..] >->
encode 10 (mapM_ yield [1..10]) >->
sequence_ (repeat $ do {x <- await; lift $ print x})
0
-2 -- remember, [0..] is negated by upsample, then multiplied by [1..10]
-6
-12
-20
-30
-42
-56
-72
-90 -- only 10 items were available in `cp`, so only 10 items printed
这篇关于重构管道界面的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!