The problematic part is the following branch in the definition of bypass, which introduces the Get to then be able to Put:bypass bs [] (Put c sp) = Get $ \ ~(b, d) -> Put (c, d) (bypass (bs ++ [b]) [] sp)如果要编写期望类型的东西,这是您需要做的,但这无疑不是一件自然的事情.It is what you need to do if you want to write something of the expected type, but it is arguably not a natural thing to do.首先定义 是导致定义和使用具有非直观语义的(&&&)运算符的原因.要了解其不直观的原因,请以 Void 作为流输入类型来专门化(&&&):Having defined first is what leads to defining and using the (&&&) operator, which has unintuitive semantics. To see why it's unintuitive, specialize (&&&) with Void as the stream input type:(&&&) :: SP Void b -> SP Void c -> SP Void (b, c)任何看过这个的人都会认为,结果当然必须是生产者,而生产者永远不会获取任何东西,这是荒谬的.除了(&&&)做荒唐的事情;因此专门用于 Void ,从道德上讲等效于以下内容(忽略了 undefined 的存在,该技术可以在Haskell中将它们区分开):Anyone who looks at this would think that, of course, the result must be a producer, which never Gets anything, that would be absurd. Except that (&&&) does the absurd thing; thus specialized to Void, it is morally equivalent to the following (ignoring the existence of undefined which can technically be used to tell them apart in Haskell):_ &&& _ = Get (absurd :: Void -> SP a c)通过对流进行递归可以更自然地定义(&&&),从而避免了该问题:如果两个参数从不执行任何 Get ,那么结果也不会执行任何 Get .There is a more natural definition of (&&&) by recursion on streams which avoids that issue: if the two arguments never do any Get, then the result never does any Get either.据我所知,这种更好"的含义是(&&)不能使用 first ,(>>>)和 arr .As far as I can tell, this "better" (&&&) cannot be defined using first, (>>>) and arr.但是,这是有代价的:从箭头的图形解释的角度来看,它是不直观的,因为它打破了这个等式(可以用滑动" f 的图形表示超出&& ):However, it comes at cost: it is not intuitive from the point of view of a graphical interpretation of arrows, because it breaks this equation (which can be drawn graphically as "sliding" f out of &&&):f &&& g = (id &&& g) >>> first f您选择的(&&&)的定义,都会使某人感到困惑.Whichever definition of (&&&) you choose, it is going to confuse someone. IMO,它归结为 StreamProcessor 类型,无法排除使用 Get 的情况.即使输入类型是 Void ,流仍然可以做空虚的 Get .IMO it comes down to the type StreamProcessor not being able to rule out the use of Get. Even if the input type is Void, a stream can still do a vacuous Get.一种没有此类定义问题的更好类型的流处理器是 pipes库中的一种.(称为 Proxy ).特别是,它与 SP 不同,因为它可以禁止使用 Get ,并且可以对真实的生产者"提供忠实的编码.例如斐波那契流.A better type of stream processor without such definitional issues is the one from the pipes library (called Proxy). In particular, it differs from SP because it can forbid the use of Get, and that provides a faithful encoding of true "producers" such as the Fibonacci stream. 这篇关于休斯的斐波那契流的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云!
07-24 07:25