重构管道界面 [英] Refactor pipes interface

查看:144
本文介绍了重构管道界面的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用管道库(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))

  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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆