流处理器的ArrowCircuit实例可能会阻塞 [英] An ArrowCircuit instance for stream processors which could block

查看:51
本文介绍了流处理器的ArrowCircuit实例可能会阻塞的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Control.Arrow.Operations.ArrowCircuit 类用于:

可用于解释同步电路的箭头类型.

An arrow type that can be used to interpret synchronous circuits.

我想知道同步在这里是什么意思.我在 Wikipedia 上进行了查找,他们在这里谈论数字电子.我的电子设备很生锈,所以这里有个问题:所谓的异步流处理器这样的实例有什么问题(如果有的话):

I want to know what synchronous means here. I looked it up on Wikipedia, where they are speaking of digital electronics. My electronics is quite rusty, so here is the question: what is wrong (if anything is) with such an instance for the so-called asynchronous stream processors:

data StreamProcessor a b = Get (a -> StreamProcessor a b) | 
                           Put b    (StreamProcessor a b) |
                           Halt

instance Category StreamProcessor where
    id = Get (\ x -> Put x id)
  
    Put c bc . ab = Put c (bc . ab)
    Get bbc . Put b ab = (bbc b) . ab
    Get bbc . Get aab = Get $ \ a -> (Get bbc) . (aab a)
    Get bbc . Halt = Halt
    Halt . ab = Halt

instance Arrow StreamProcessor where
    ...

getThroughBlocks :: [a] -> StreamProcessor a b -> StreamProcessor a b
getThroughBlocks ~(a : input) (Get f)   = getThroughBlocks input (f a)
getThroughBlocks _input       putOrHalt = putOrHalt

getThroughSameArgBlocks :: a -> StreamProcessor a b -> StreamProcessor a b
getThroughSameArgBlocks = getThroughBlocks . repeat

instance ArrowLoop StreamProcessor where
    loop Halt               = Halt
    loop (Put (c, d) bdcd') = Put c (loop bdcd')
    loop (Get f)            = Get $ \ b -> 
         let 
            Put (c, d) bdcd' = getThroughSameArgBlocks (b, d) (f (b, d))
         in Put c (loop bdcd')

instance ArrowCircuit StreamProcessor where
    delay b = Put b id

我认为此解决方案可为我们工作,因为:我们希望 someArrowCircuit>>>延迟b someArrowCircuit 延迟一刻,其​​中 b 出现在它之前.很容易看到我们得到了我们想要的东西:

I reckon this solution to work for us as: we want someArrowCircuit >>> delay b to be someArrowCircuit delayed by one tick with b coming before anything from it. It is easy to see we get what we want:

someArrowCircuit >>> delay b
= someArrowCircuit >>> Put b id 
= Put b id . someArrowCircuit
= Put b (id . someArrowCircuit)
= Put b someArrowCircuit

此类课程是否有法律?如果我没记错地写下 delay 同步 异步并存的情况如何?

Are there any laws for such a class? If I made no mistake writing delay down, how does synchronous live alongside asynchronous?

推荐答案

我知道的唯一与 ArrowCircuit 相关的法律实际上是针对原因换向箭头,它表示 delay i ***延迟j =延迟(i,j).我很确定您的版本可以满足此要求(并且看起来完全是合理的实现),但是考虑到 StreamProcessor 不是同步的,它仍然有些奇怪.

The only law that I know of related to ArrowCircuit is actually for the similar ArrowInit class from Causal Commutative Arrows, which says that delay i *** delay j = delay (i,j). I'm pretty sure your version satisfies this (and it looks like a totally reasonable implementation), but it still feels a little strange considering that StreamProcessor isn't synchronous.

特别地,同步电路遵循产生单个输出的单个输入的模式.例如,如果您有一个 Circuit a b ,并为其提供类型为 a 的值,那么您将获得一个且只有一个输出 b .该一滴答的延迟"指的是一滴答的延迟".因此, delay 引入的延迟是一个输出的一级延迟.

Particularly, synchronous circuits follow a pattern of a single input producing a single output. For example, if you have a Circuit a b and provide it a value of type a, then you will get one and only one output b. The "one-tick delay" that delay introduces is thus a delay of one output by one step.

但是对于异步电路来说,这有点时髦.我们来看一个例子:

But things are a little funky for asynchronous circuits. Let's consider an example:

runStreamProcessor :: StreamProcessor a b -> [a] -> [b]
runStreamProcessor (Put x s) xs = x : runStreamProcessor s xs
runStreamProcessor _ [] = []
runStreamProcessor Halt _ = []
runStreamProcessor (Get f) (x:xs) = runStreamProcessor (f x) xs

multiplyOneThroughFive :: StreamProcessor Int Int
multiplyOneThroughFive = Get $ \x -> 
  Put (x*1) $ Put (x*2) $ Put (x*3) $ Put (x*4) $ Put (x*5) multiplyOneThroughFive

在这里, multiplyOneThroughFive 对于收到的每个输入产生5个输出.现在,考虑 multiplyOneThroughFive>>>与延迟100 delay 100>>multipleOneThroughFive :

Here, multiplyOneThroughFive produces 5 outputs for each input it receives. Now, consider the difference between multiplyOneThroughFive >>> delay 100 and delay 100 >>> multiplyOneThroughFive:

> runStreamProcessor (multiplyOneThroughFive >>> delay 100) [1,2]
[100,1,2,3,4,5,2,4,6,8,10]
> runStreamProcessor (delay 100 >>> multiplyOneThroughFive) [1,2]
[100,200,300,400,500,1,2,3,4,5,2,4,6,8,10]

在电路的另一点插入 delay 实际上会使我们产生不同数量的结果.实际上,电路似乎整体上经历了5滴答的延迟,而不是仅仅1滴答的延迟.在同步环境中,这肯定是意外行为!

Inserting the delay at a different point in the circuit actually caused us to produce a different number of results. Indeed, it seems as if the circuit as a whole underwent a 5-tick delay instead of just a 1-tick delay. This would definitely be unexpected behavior in a synchronous environment!

这篇关于流处理器的ArrowCircuit实例可能会阻塞的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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