加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

haskell – 用于将数据处理表示为管道的框架

发布时间:2020-12-14 03:19:32 所属栏目:大数据 来源:网络整理
导读:大多数数据处理可以设想为一个组件流水线,一个输入输入到另一个输入端。一个典型的处理流程是: reader | handler | writer 作为开始讨论的一个幌子,让我们考虑一下这个管道的面向对象实现,其中每个段都是一个对象。处理程序对象包含对reader和writer对象
大多数数据处理可以设想为一个组件流水线,一个输入输入到另一个输入端。一个典型的处理流程是:

reader | handler | writer

作为开始讨论的一个幌子,让我们考虑一下这个管道的面向对象实现,其中每个段都是一个对象。处理程序对象包含对reader和writer对象的引用,并且具有如下所示的运行方法:

define handler.run:
  while (reader.has_next) {
    data = reader.next
    output = ...some function of data...
    writer.put(output)
  }

依赖关系是:

reader <- handler -> writer

现在假设我想在阅读器和处理程序之间插入一个新的管道段:

reader | tweaker | handler | writer

再次,在这个OO实现中,调整器将是读取器对象的包装器,并且调整器方法可能看起来像(在一些伪命令代码中):

define tweaker.has_next:
  return reader.has_next

define tweaker.next:
  value = reader.next
  result = ...some function of value...
  return result

我发现这不是一个非常可组合的抽象。一些问题是:

>调整器只能在处理程序的左侧使用,即我不能使用上述的调整器实现来形成这个管道:

读者|处理程序|调节器|作家
>我想利用管道的关联属性,这样管道:

读者|处理程序|作家

可以表示为:

reader | p

其中p是流水线处理程序|作家。在这个OO实现中,我将必须部分地实例化处理程序对象

>(1)重申一些,对象必须知道他们是“推”还是“拉”数据。

我正在寻找一个框架(不一定是OO)来创建解决这些问题的数据处理流水线。

我用Haskell和函数编程标记了这一点,因为我觉得功能编程概念在这里可能是有用的。

作为一个目标,可以创建一个这样的管道是很好的:

handler1
                   /          
reader | partition              writer
                             /
                     handler2

对于某些角度来说,Unix shell管道解决了以下实现决策中的很多这些问题:

>管道组件在不同的进程中异步运行
管道对象介于“推动者”和“牵引人”之间传递数据;即它们阻止写入数据的作者太快,读者试图读取的速度太快。
>使用特殊连接器<和>将无源组件(即文件)连接到管道

我对不使用线程或代理之间的消息传递的方法特别感兴趣。也许这是最好的方法,但如果可能,我想避免线程。

谢谢!

解决方法

是的, arrows几乎肯定是你的男人。

我怀疑你是Haskell的新手,只是根据你在你的问题上所说的那些事情。箭头可能看起来很抽象,特别是如果你正在寻找的是一个“框架”。我知道花了我一段时间才能真正了解箭头发生了什么。

所以你可以看看那个页面,并说“是的,这看起来像我想要的”,然后发现自己相当迷失如何开始使用箭头来解决问题。所以这里有一点指导,所以你知道你在看什么。

箭头不会解决你的问题。相反,他们给你一种你可以用来说明你的问题的语言。你可能会发现一些预定义的箭头可以完成这个工作 – 也许某些kleisli箭头可能是 – 但是在一天的最后,你将要实现一个箭头(预定义的箭头只是给你简单的方法来实现)什么意思是“数据处理器”。作为一个简单的例子,我们假设你想通过简单的功能来实现你的数据处理器。你会写:

newtype Proc a b = Proc { unProc :: a -> b }

-- I believe Arrow has recently become a subclass of Category,so assuming that.

instance Category Proc where
    id = Proc (x -> x)
    Proc f . Proc g = Proc (x -> f (g x))

instance Arrow Proc where
    arr f = Proc f
    first (Proc f) = Proc ((x,y) -> (f x,y))

这使您可以使用各种箭头组合器(***),(&&),(>>>)等,以及箭头符号,如果您正在做复杂的事情。所以,正如Daniel Fischer在评论中指出的那样,你在问题中描述的管道可以由以下组成:

reader >>> partition >>> (handler1 *** handler2) >>> writer

但很酷的事情是,由你处理器的意思是由你决定的。使用不同的处理器类型,可以以类似的方式实现您提到的关于每个处理器分叉线程的内容:

newtype Proc' a b = Proc (Source a -> Sink b -> IO ())

然后适当地实施组合器。

所以这就是你正在看的:一个谈论组合流程的词汇表,它有一点点重用的代码,但主要将帮助指导你的想法,因为你实现这些组合器来定义在你的域中有用的处理器。

我的第一个非常平凡的Haskell项目之一是实施arrow for quantum entanglement;那个项目是让我真正开始了解Haskell思维方式的一个项目,这是我的编程生涯的一个重大转折点。也许这个你的项目会为你做同样的事情?

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读